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