| 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 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1074 | 1074 |
| 1075 HValue* HGraphBuilder::BuildCheckNonSmi(HValue* obj) { | 1075 HValue* HGraphBuilder::BuildCheckNonSmi(HValue* obj) { |
| 1076 HCheckNonSmi* check = new(zone()) HCheckNonSmi(obj); | 1076 HCheckNonSmi* check = new(zone()) HCheckNonSmi(obj); |
| 1077 AddInstruction(check); | 1077 AddInstruction(check); |
| 1078 return check; | 1078 return check; |
| 1079 } | 1079 } |
| 1080 | 1080 |
| 1081 | 1081 |
| 1082 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, | 1082 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, |
| 1083 Handle<Map> map) { | 1083 Handle<Map> map) { |
| 1084 HCheckMaps* check = new(zone()) HCheckMaps(obj, map, zone()); | 1084 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); |
| 1085 AddInstruction(check); | 1085 AddInstruction(check); |
| 1086 return check; | 1086 return check; |
| 1087 } | 1087 } |
| 1088 | 1088 |
| 1089 | 1089 |
| 1090 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( | 1090 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
| 1091 HValue* external_elements, | 1091 HValue* external_elements, |
| 1092 HValue* checked_key, | 1092 HValue* checked_key, |
| 1093 HValue* val, | 1093 HValue* val, |
| 1094 HValue* dependency, | 1094 HValue* dependency, |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1290 if (mapcheck != NULL) { | 1290 if (mapcheck != NULL) { |
| 1291 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 1291 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
| 1292 } | 1292 } |
| 1293 } | 1293 } |
| 1294 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); | 1294 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); |
| 1295 bool fast_elements = IsFastObjectElementsKind(elements_kind); | 1295 bool fast_elements = IsFastObjectElementsKind(elements_kind); |
| 1296 HValue* elements = | 1296 HValue* elements = |
| 1297 AddInstruction(new(zone) HLoadElements(object, mapcheck)); | 1297 AddInstruction(new(zone) HLoadElements(object, mapcheck)); |
| 1298 if (is_store && (fast_elements || fast_smi_only_elements) && | 1298 if (is_store && (fast_elements || fast_smi_only_elements) && |
| 1299 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { | 1299 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { |
| 1300 HCheckMaps* check_cow_map = new(zone) HCheckMaps( | 1300 HCheckMaps* check_cow_map = HCheckMaps::New( |
| 1301 elements, isolate()->factory()->fixed_array_map(), zone); | 1301 elements, isolate()->factory()->fixed_array_map(), zone); |
| 1302 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 1302 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
| 1303 AddInstruction(check_cow_map); | 1303 AddInstruction(check_cow_map); |
| 1304 } | 1304 } |
| 1305 HInstruction* length = NULL; | 1305 HInstruction* length = NULL; |
| 1306 if (is_js_array) { | 1306 if (is_js_array) { |
| 1307 length = AddInstruction( | 1307 length = AddInstruction( |
| 1308 HLoadNamedField::NewArrayLength(zone, object, mapcheck, HType::Smi())); | 1308 HLoadNamedField::NewArrayLength(zone, object, mapcheck, HType::Smi())); |
| 1309 } else { | 1309 } else { |
| 1310 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1310 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1364 checked_key = AddBoundsCheck( | 1364 checked_key = AddBoundsCheck( |
| 1365 key, length, ALLOW_SMI_KEY, checked_index_representation); | 1365 key, length, ALLOW_SMI_KEY, checked_index_representation); |
| 1366 | 1366 |
| 1367 if (is_store && (fast_elements || fast_smi_only_elements)) { | 1367 if (is_store && (fast_elements || fast_smi_only_elements)) { |
| 1368 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { | 1368 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { |
| 1369 NoObservableSideEffectsScope no_effects(this); | 1369 NoObservableSideEffectsScope no_effects(this); |
| 1370 | 1370 |
| 1371 elements = BuildCopyElementsOnWrite(object, elements, elements_kind, | 1371 elements = BuildCopyElementsOnWrite(object, elements, elements_kind, |
| 1372 length); | 1372 length); |
| 1373 } else { | 1373 } else { |
| 1374 HCheckMaps* check_cow_map = new(zone) HCheckMaps( | 1374 HCheckMaps* check_cow_map = HCheckMaps::New( |
| 1375 elements, isolate()->factory()->fixed_array_map(), zone); | 1375 elements, isolate()->factory()->fixed_array_map(), zone); |
| 1376 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 1376 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
| 1377 AddInstruction(check_cow_map); | 1377 AddInstruction(check_cow_map); |
| 1378 } | 1378 } |
| 1379 } | 1379 } |
| 1380 } | 1380 } |
| 1381 return AddInstruction( | 1381 return AddInstruction( |
| 1382 BuildFastElementAccess(elements, checked_key, val, mapcheck, | 1382 BuildFastElementAccess(elements, checked_key, val, mapcheck, |
| 1383 elements_kind, is_store, store_mode)); | 1383 elements_kind, is_store, store_mode)); |
| 1384 } | 1384 } |
| (...skipping 5260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6645 return lookup->GetLocalFieldIndexFromMap(*type); | 6645 return lookup->GetLocalFieldIndexFromMap(*type); |
| 6646 } else { | 6646 } else { |
| 6647 Map* transition = lookup->GetTransitionMapFromMap(*type); | 6647 Map* transition = lookup->GetTransitionMapFromMap(*type); |
| 6648 return transition->PropertyIndexFor(*name) - type->inobject_properties(); | 6648 return transition->PropertyIndexFor(*name) - type->inobject_properties(); |
| 6649 } | 6649 } |
| 6650 } | 6650 } |
| 6651 | 6651 |
| 6652 | 6652 |
| 6653 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { | 6653 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { |
| 6654 AddInstruction(new(zone()) HCheckNonSmi(object)); | 6654 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 6655 AddInstruction(new(zone()) HCheckMaps(object, map, zone())); | 6655 AddInstruction(HCheckMaps::New(object, map, zone())); |
| 6656 } | 6656 } |
| 6657 | 6657 |
| 6658 | 6658 |
| 6659 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, | 6659 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, |
| 6660 Handle<Map> map) { | 6660 Handle<Map> map) { |
| 6661 AddInstruction(new(zone()) HCheckNonSmi(object)); | 6661 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 6662 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); | 6662 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); |
| 6663 } | 6663 } |
| 6664 | 6664 |
| 6665 | 6665 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6774 Handle<String> name) { | 6774 Handle<String> name) { |
| 6775 if (!name->Equals(isolate()->heap()->length_string())) return false; | 6775 if (!name->Equals(isolate()->heap()->length_string())) return false; |
| 6776 | 6776 |
| 6777 for (int i = 0; i < types->length(); i++) { | 6777 for (int i = 0; i < types->length(); i++) { |
| 6778 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false; | 6778 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false; |
| 6779 } | 6779 } |
| 6780 | 6780 |
| 6781 AddInstruction(new(zone()) HCheckNonSmi(object)); | 6781 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 6782 | 6782 |
| 6783 HInstruction* typecheck = | 6783 HInstruction* typecheck = |
| 6784 AddInstruction(new(zone()) HCheckMaps(object, types, zone())); | 6784 AddInstruction(HCheckMaps::New(object, types, zone())); |
| 6785 HInstruction* instr = | 6785 HInstruction* instr = |
| 6786 HLoadNamedField::NewArrayLength(zone(), object, typecheck); | 6786 HLoadNamedField::NewArrayLength(zone(), object, typecheck); |
| 6787 instr->set_position(expr->position()); | 6787 instr->set_position(expr->position()); |
| 6788 ast_context()->ReturnInstruction(instr, expr->id()); | 6788 ast_context()->ReturnInstruction(instr, expr->id()); |
| 6789 return true; | 6789 return true; |
| 6790 } | 6790 } |
| 6791 | 6791 |
| 6792 | 6792 |
| 6793 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, | 6793 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, |
| 6794 HValue* object, | 6794 HValue* object, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6826 } | 6826 } |
| 6827 ++count; | 6827 ++count; |
| 6828 } | 6828 } |
| 6829 } | 6829 } |
| 6830 | 6830 |
| 6831 // Use monomorphic load if property lookup results in the same field index | 6831 // Use monomorphic load if property lookup results in the same field index |
| 6832 // for all maps. Requires special map check on the set of all handled maps. | 6832 // for all maps. Requires special map check on the set of all handled maps. |
| 6833 AddInstruction(new(zone()) HCheckNonSmi(object)); | 6833 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 6834 HInstruction* instr; | 6834 HInstruction* instr; |
| 6835 if (count == types->length() && is_monomorphic_field) { | 6835 if (count == types->length() && is_monomorphic_field) { |
| 6836 AddInstruction(new(zone()) HCheckMaps(object, types, zone())); | 6836 AddInstruction(HCheckMaps::New(object, types, zone())); |
| 6837 instr = BuildLoadNamedField(object, map, &lookup); | 6837 instr = BuildLoadNamedField(object, map, &lookup); |
| 6838 } else { | 6838 } else { |
| 6839 HValue* context = environment()->LookupContext(); | 6839 HValue* context = environment()->LookupContext(); |
| 6840 instr = new(zone()) HLoadNamedFieldPolymorphic(context, | 6840 instr = new(zone()) HLoadNamedFieldPolymorphic(context, |
| 6841 object, | 6841 object, |
| 6842 types, | 6842 types, |
| 6843 name, | 6843 name, |
| 6844 zone()); | 6844 zone()); |
| 6845 } | 6845 } |
| 6846 | 6846 |
| (...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7503 | 7503 |
| 7504 | 7504 |
| 7505 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( | 7505 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( |
| 7506 HValue* object, | 7506 HValue* object, |
| 7507 HValue* key, | 7507 HValue* key, |
| 7508 HValue* val, | 7508 HValue* val, |
| 7509 HValue* dependency, | 7509 HValue* dependency, |
| 7510 Handle<Map> map, | 7510 Handle<Map> map, |
| 7511 bool is_store, | 7511 bool is_store, |
| 7512 KeyedAccessStoreMode store_mode) { | 7512 KeyedAccessStoreMode store_mode) { |
| 7513 HCheckMaps* mapcheck = new(zone()) HCheckMaps(object, map, | 7513 HCheckMaps* mapcheck = HCheckMaps::New(object, map, zone(), dependency); |
| 7514 zone(), dependency); | |
| 7515 AddInstruction(mapcheck); | 7514 AddInstruction(mapcheck); |
| 7516 if (dependency) { | 7515 if (dependency) { |
| 7517 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 7516 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
| 7518 } | 7517 } |
| 7519 return BuildUncheckedMonomorphicElementAccess( | 7518 return BuildUncheckedMonomorphicElementAccess( |
| 7520 object, key, val, | 7519 object, key, val, |
| 7521 mapcheck, map->instance_type() == JS_ARRAY_TYPE, | 7520 mapcheck, map->instance_type() == JS_ARRAY_TYPE, |
| 7522 map->elements_kind(), is_store, store_mode); | 7521 map->elements_kind(), is_store, store_mode); |
| 7523 } | 7522 } |
| 7524 | 7523 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7561 // Remember the most general elements kind, the code for its load will | 7560 // Remember the most general elements kind, the code for its load will |
| 7562 // properly handle all of the more specific cases. | 7561 // properly handle all of the more specific cases. |
| 7563 if ((i == 0) || IsMoreGeneralElementsKindTransition( | 7562 if ((i == 0) || IsMoreGeneralElementsKindTransition( |
| 7564 most_general_consolidated_map->elements_kind(), | 7563 most_general_consolidated_map->elements_kind(), |
| 7565 map->elements_kind())) { | 7564 map->elements_kind())) { |
| 7566 most_general_consolidated_map = map; | 7565 most_general_consolidated_map = map; |
| 7567 } | 7566 } |
| 7568 } | 7567 } |
| 7569 if (!has_double_maps && !has_smi_or_object_maps) return NULL; | 7568 if (!has_double_maps && !has_smi_or_object_maps) return NULL; |
| 7570 | 7569 |
| 7571 HCheckMaps* check_maps = new(zone()) HCheckMaps(object, maps, zone()); | 7570 HCheckMaps* check_maps = HCheckMaps::New(object, maps, zone()); |
| 7572 AddInstruction(check_maps); | 7571 AddInstruction(check_maps); |
| 7573 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( | 7572 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( |
| 7574 object, key, val, check_maps, | 7573 object, key, val, check_maps, |
| 7575 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, | 7574 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, |
| 7576 most_general_consolidated_map->elements_kind(), | 7575 most_general_consolidated_map->elements_kind(), |
| 7577 false, STANDARD_STORE); | 7576 false, STANDARD_STORE); |
| 7578 return instr; | 7577 return instr; |
| 7579 } | 7578 } |
| 7580 | 7579 |
| 7581 | 7580 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7713 new(zone()) HCompareConstantEqAndBranch( | 7712 new(zone()) HCompareConstantEqAndBranch( |
| 7714 elements_kind_instr, elements_kind, Token::EQ_STRICT); | 7713 elements_kind_instr, elements_kind, Token::EQ_STRICT); |
| 7715 elements_kind_branch->SetSuccessorAt(0, if_true); | 7714 elements_kind_branch->SetSuccessorAt(0, if_true); |
| 7716 elements_kind_branch->SetSuccessorAt(1, if_false); | 7715 elements_kind_branch->SetSuccessorAt(1, if_false); |
| 7717 current_block()->Finish(elements_kind_branch); | 7716 current_block()->Finish(elements_kind_branch); |
| 7718 | 7717 |
| 7719 set_current_block(if_true); | 7718 set_current_block(if_true); |
| 7720 HInstruction* access; | 7719 HInstruction* access; |
| 7721 if (IsFastElementsKind(elements_kind)) { | 7720 if (IsFastElementsKind(elements_kind)) { |
| 7722 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { | 7721 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { |
| 7723 AddInstruction(new(zone()) HCheckMaps( | 7722 AddInstruction(HCheckMaps::New( |
| 7724 elements, isolate()->factory()->fixed_array_map(), | 7723 elements, isolate()->factory()->fixed_array_map(), |
| 7725 zone(), elements_kind_branch)); | 7724 zone(), elements_kind_branch)); |
| 7726 } | 7725 } |
| 7727 // TODO(jkummerow): The need for these two blocks could be avoided | 7726 // TODO(jkummerow): The need for these two blocks could be avoided |
| 7728 // in one of two ways: | 7727 // in one of two ways: |
| 7729 // (1) Introduce ElementsKinds for JSArrays that are distinct from | 7728 // (1) Introduce ElementsKinds for JSArrays that are distinct from |
| 7730 // those for fast objects. | 7729 // those for fast objects. |
| 7731 // (2) Put the common instructions into a third "join" block. This | 7730 // (2) Put the common instructions into a third "join" block. This |
| 7732 // requires additional AST IDs that we can deopt to from inside | 7731 // requires additional AST IDs that we can deopt to from inside |
| 7733 // that join block. They must be added to the Property class (when | 7732 // that join block. They must be added to the Property class (when |
| (...skipping 4140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11874 } | 11873 } |
| 11875 } | 11874 } |
| 11876 | 11875 |
| 11877 #ifdef DEBUG | 11876 #ifdef DEBUG |
| 11878 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11877 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 11879 if (allocator_ != NULL) allocator_->Verify(); | 11878 if (allocator_ != NULL) allocator_->Verify(); |
| 11880 #endif | 11879 #endif |
| 11881 } | 11880 } |
| 11882 | 11881 |
| 11883 } } // namespace v8::internal | 11882 } } // namespace v8::internal |
| OLD | NEW |