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 |