Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: src/hydrogen.cc

Issue 12208013: Separated smi check from HBoundsCheck. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Removed platform specific code. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 761 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 } 772 }
773 773
774 774
775 void HGraphBuilder::AddSimulate(BailoutId id, 775 void HGraphBuilder::AddSimulate(BailoutId id,
776 RemovableSimulate removable) { 776 RemovableSimulate removable) {
777 ASSERT(current_block() != NULL); 777 ASSERT(current_block() != NULL);
778 current_block()->AddSimulate(id, removable); 778 current_block()->AddSimulate(id, removable);
779 } 779 }
780 780
781 781
782 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index,
783 HValue* length,
784 BoundsCheckKeyMode key_mode,
785 Representation r) {
786 HCheckSmiOrInt32* checked_index =
787 new(graph()->zone()) HCheckSmiOrInt32(index);
788 AddInstruction(checked_index);
789 HBoundsCheck* result = new(graph()->zone()) HBoundsCheck(
790 checked_index, length, key_mode, r);
791 AddInstruction(result);
792 return result;
793 }
794
795
782 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { 796 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
783 HBasicBlock* b = graph()->CreateBasicBlock(); 797 HBasicBlock* b = graph()->CreateBasicBlock();
784 b->SetInitialEnvironment(env); 798 b->SetInitialEnvironment(env);
785 return b; 799 return b;
786 } 800 }
787 801
788 802
789 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { 803 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() {
790 HBasicBlock* header = graph()->CreateBasicBlock(); 804 HBasicBlock* header = graph()->CreateBasicBlock();
791 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); 805 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 if (is_store && (fast_elements || fast_smi_only_elements)) { 925 if (is_store && (fast_elements || fast_smi_only_elements)) {
912 HCheckMaps* check_cow_map = new(zone) HCheckMaps( 926 HCheckMaps* check_cow_map = new(zone) HCheckMaps(
913 elements, Isolate::Current()->factory()->fixed_array_map(), zone); 927 elements, Isolate::Current()->factory()->fixed_array_map(), zone);
914 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 928 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
915 AddInstruction(check_cow_map); 929 AddInstruction(check_cow_map);
916 } 930 }
917 HInstruction* length = NULL; 931 HInstruction* length = NULL;
918 HInstruction* checked_key = NULL; 932 HInstruction* checked_key = NULL;
919 if (IsExternalArrayElementsKind(elements_kind)) { 933 if (IsExternalArrayElementsKind(elements_kind)) {
920 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); 934 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements));
921 checked_key = AddInstruction(new(zone) HBoundsCheck( 935 checked_key = AddBoundsCheck(
922 key, length, ALLOW_SMI_KEY, checked_index_representation)); 936 key, length, ALLOW_SMI_KEY, checked_index_representation);
923 HLoadExternalArrayPointer* external_elements = 937 HLoadExternalArrayPointer* external_elements =
924 new(zone) HLoadExternalArrayPointer(elements); 938 new(zone) HLoadExternalArrayPointer(elements);
925 AddInstruction(external_elements); 939 AddInstruction(external_elements);
926 return BuildExternalArrayElementAccess( 940 return BuildExternalArrayElementAccess(
927 external_elements, checked_key, val, mapcheck, 941 external_elements, checked_key, val, mapcheck,
928 elements_kind, is_store); 942 elements_kind, is_store);
929 } 943 }
930 ASSERT(fast_smi_only_elements || 944 ASSERT(fast_smi_only_elements ||
931 fast_elements || 945 fast_elements ||
932 IsFastDoubleElementsKind(elements_kind)); 946 IsFastDoubleElementsKind(elements_kind));
933 if (is_js_array) { 947 if (is_js_array) {
934 length = AddInstruction(new(zone) HJSArrayLength(object, mapcheck, 948 length = AddInstruction(new(zone) HJSArrayLength(object, mapcheck,
935 HType::Smi())); 949 HType::Smi()));
936 } else { 950 } else {
937 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); 951 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements));
938 } 952 }
939 checked_key = AddInstruction(new(zone) HBoundsCheck( 953 checked_key = AddBoundsCheck(
940 key, length, ALLOW_SMI_KEY, checked_index_representation)); 954 key, length, ALLOW_SMI_KEY, checked_index_representation);
941 return BuildFastElementAccess(elements, checked_key, val, mapcheck, 955 return BuildFastElementAccess(elements, checked_key, val, mapcheck,
942 elements_kind, is_store); 956 elements_kind, is_store);
943 } 957 }
944 958
945 959
946 HValue* HGraphBuilder::BuildAllocateElements(HContext* context, 960 HValue* HGraphBuilder::BuildAllocateElements(HContext* context,
947 ElementsKind kind, 961 ElementsKind kind,
948 HValue* capacity) { 962 HValue* capacity) {
949 Zone* zone = this->zone(); 963 Zone* zone = this->zone();
950 964
(...skipping 5875 matching lines...) Expand 10 before | Expand all | Expand 10 after
6826 elements_kind <= LAST_ELEMENTS_KIND; 6840 elements_kind <= LAST_ELEMENTS_KIND;
6827 elements_kind = ElementsKind(elements_kind + 1)) { 6841 elements_kind = ElementsKind(elements_kind + 1)) {
6828 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some 6842 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some
6829 // code that's executed for all external array cases. 6843 // code that's executed for all external array cases.
6830 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == 6844 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND ==
6831 LAST_ELEMENTS_KIND); 6845 LAST_ELEMENTS_KIND);
6832 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND 6846 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND
6833 && todo_external_array) { 6847 && todo_external_array) {
6834 HInstruction* length = 6848 HInstruction* length =
6835 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); 6849 AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
6836 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 6850 checked_key = AddBoundsCheck(key, length);
6837 external_elements = new(zone()) HLoadExternalArrayPointer(elements); 6851 external_elements = new(zone()) HLoadExternalArrayPointer(elements);
6838 AddInstruction(external_elements); 6852 AddInstruction(external_elements);
6839 } 6853 }
6840 if (type_todo[elements_kind]) { 6854 if (type_todo[elements_kind]) {
6841 HBasicBlock* if_true = graph()->CreateBasicBlock(); 6855 HBasicBlock* if_true = graph()->CreateBasicBlock();
6842 HBasicBlock* if_false = graph()->CreateBasicBlock(); 6856 HBasicBlock* if_false = graph()->CreateBasicBlock();
6843 HCompareConstantEqAndBranch* elements_kind_branch = 6857 HCompareConstantEqAndBranch* elements_kind_branch =
6844 new(zone()) HCompareConstantEqAndBranch( 6858 new(zone()) HCompareConstantEqAndBranch(
6845 elements_kind_instr, elements_kind, Token::EQ_STRICT); 6859 elements_kind_instr, elements_kind, Token::EQ_STRICT);
6846 elements_kind_branch->SetSuccessorAt(0, if_true); 6860 elements_kind_branch->SetSuccessorAt(0, if_true);
(...skipping 21 matching lines...) Expand all
6868 HHasInstanceTypeAndBranch* typecheck = 6882 HHasInstanceTypeAndBranch* typecheck =
6869 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); 6883 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE);
6870 typecheck->SetSuccessorAt(0, if_jsarray); 6884 typecheck->SetSuccessorAt(0, if_jsarray);
6871 typecheck->SetSuccessorAt(1, if_fastobject); 6885 typecheck->SetSuccessorAt(1, if_fastobject);
6872 current_block()->Finish(typecheck); 6886 current_block()->Finish(typecheck);
6873 6887
6874 set_current_block(if_jsarray); 6888 set_current_block(if_jsarray);
6875 HInstruction* length; 6889 HInstruction* length;
6876 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck, 6890 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck,
6877 HType::Smi())); 6891 HType::Smi()));
6878 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, 6892 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY);
6879 ALLOW_SMI_KEY));
6880 access = AddInstruction(BuildFastElementAccess( 6893 access = AddInstruction(BuildFastElementAccess(
6881 elements, checked_key, val, elements_kind_branch, 6894 elements, checked_key, val, elements_kind_branch,
6882 elements_kind, is_store)); 6895 elements_kind, is_store));
6883 if (!is_store) { 6896 if (!is_store) {
6884 Push(access); 6897 Push(access);
6885 } 6898 }
6886 6899
6887 *has_side_effects |= access->HasObservableSideEffects(); 6900 *has_side_effects |= access->HasObservableSideEffects();
6888 if (position != -1) { 6901 if (position != -1) {
6889 access->set_position(position); 6902 access->set_position(position);
6890 } 6903 }
6891 if_jsarray->Goto(join); 6904 if_jsarray->Goto(join);
6892 6905
6893 set_current_block(if_fastobject); 6906 set_current_block(if_fastobject);
6894 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); 6907 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
6895 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, 6908 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY);
6896 ALLOW_SMI_KEY));
6897 access = AddInstruction(BuildFastElementAccess( 6909 access = AddInstruction(BuildFastElementAccess(
6898 elements, checked_key, val, elements_kind_branch, 6910 elements, checked_key, val, elements_kind_branch,
6899 elements_kind, is_store)); 6911 elements_kind, is_store));
6900 } else if (elements_kind == DICTIONARY_ELEMENTS) { 6912 } else if (elements_kind == DICTIONARY_ELEMENTS) {
6901 if (is_store) { 6913 if (is_store) {
6902 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); 6914 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val));
6903 } else { 6915 } else {
6904 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); 6916 access = AddInstruction(BuildLoadKeyedGeneric(object, key));
6905 } 6917 }
6906 } else { // External array elements. 6918 } else { // External array elements.
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
7035 Push(graph()->GetArgumentsObject()); 7047 Push(graph()->GetArgumentsObject());
7036 VisitForValue(expr->key()); 7048 VisitForValue(expr->key());
7037 if (HasStackOverflow() || current_block() == NULL) return true; 7049 if (HasStackOverflow() || current_block() == NULL) return true;
7038 HValue* key = Pop(); 7050 HValue* key = Pop();
7039 Drop(1); // Arguments object. 7051 Drop(1); // Arguments object.
7040 if (function_state()->outer() == NULL) { 7052 if (function_state()->outer() == NULL) {
7041 HInstruction* elements = AddInstruction( 7053 HInstruction* elements = AddInstruction(
7042 new(zone()) HArgumentsElements(false)); 7054 new(zone()) HArgumentsElements(false));
7043 HInstruction* length = AddInstruction( 7055 HInstruction* length = AddInstruction(
7044 new(zone()) HArgumentsLength(elements)); 7056 new(zone()) HArgumentsLength(elements));
7045 HInstruction* checked_key = 7057 HInstruction* checked_key = AddBoundsCheck(key, length);
7046 AddInstruction(new(zone()) HBoundsCheck(key, length));
7047 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); 7058 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key);
7048 } else { 7059 } else {
7049 EnsureArgumentsArePushedForAccess(); 7060 EnsureArgumentsArePushedForAccess();
7050 7061
7051 // Number of arguments without receiver. 7062 // Number of arguments without receiver.
7052 HInstruction* elements = function_state()->arguments_elements(); 7063 HInstruction* elements = function_state()->arguments_elements();
7053 int argument_count = environment()-> 7064 int argument_count = environment()->
7054 arguments_environment()->parameter_count() - 1; 7065 arguments_environment()->parameter_count() - 1;
7055 HInstruction* length = AddInstruction(new(zone()) HConstant( 7066 HInstruction* length = AddInstruction(new(zone()) HConstant(
7056 Handle<Object>(Smi::FromInt(argument_count)), 7067 Handle<Object>(Smi::FromInt(argument_count)),
7057 Representation::Integer32())); 7068 Representation::Integer32()));
7058 HInstruction* checked_key = 7069 HInstruction* checked_key = AddBoundsCheck(key, length);
7059 AddInstruction(new(zone()) HBoundsCheck(key, length));
7060 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); 7070 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key);
7061 } 7071 }
7062 } 7072 }
7063 ast_context()->ReturnInstruction(result, expr->id()); 7073 ast_context()->ReturnInstruction(result, expr->id());
7064 return true; 7074 return true;
7065 } 7075 }
7066 7076
7067 7077
7068 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { 7078 void HOptimizedGraphBuilder::VisitProperty(Property* expr) {
7069 ASSERT(!HasStackOverflow()); 7079 ASSERT(!HasStackOverflow());
(...skipping 1693 matching lines...) Expand 10 before | Expand all | Expand 10 after
8763 8773
8764 8774
8765 HStringCharCodeAt* HOptimizedGraphBuilder::BuildStringCharCodeAt( 8775 HStringCharCodeAt* HOptimizedGraphBuilder::BuildStringCharCodeAt(
8766 HValue* context, 8776 HValue* context,
8767 HValue* string, 8777 HValue* string,
8768 HValue* index) { 8778 HValue* index) {
8769 AddInstruction(new(zone()) HCheckNonSmi(string)); 8779 AddInstruction(new(zone()) HCheckNonSmi(string));
8770 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 8780 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
8771 HStringLength* length = new(zone()) HStringLength(string); 8781 HStringLength* length = new(zone()) HStringLength(string);
8772 AddInstruction(length); 8782 AddInstruction(length);
8773 HInstruction* checked_index = 8783 HInstruction* checked_index = AddBoundsCheck(index, length);
8774 AddInstruction(new(zone()) HBoundsCheck(index, length));
8775 return new(zone()) HStringCharCodeAt(context, string, checked_index); 8784 return new(zone()) HStringCharCodeAt(context, string, checked_index);
8776 } 8785 }
8777 8786
8778 // Checks if the given shift amounts have form: (sa) and (32 - sa). 8787 // Checks if the given shift amounts have form: (sa) and (32 - sa).
8779 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, 8788 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
8780 HValue* const32_minus_sa) { 8789 HValue* const32_minus_sa) {
8781 if (!const32_minus_sa->IsSub()) return false; 8790 if (!const32_minus_sa->IsSub()) return false;
8782 HSub* sub = HSub::cast(const32_minus_sa); 8791 HSub* sub = HSub::cast(const32_minus_sa);
8783 if (sa != sub->right()) return false; 8792 if (sa != sub->right()) return false;
8784 HValue* const32 = sub->left(); 8793 HValue* const32 = sub->left();
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
9592 // Our implementation of arguments (based on this stack frame or an 9601 // Our implementation of arguments (based on this stack frame or an
9593 // adapter below it) does not work for inlined functions. This runtime 9602 // adapter below it) does not work for inlined functions. This runtime
9594 // function is blacklisted by AstNode::IsInlineable. 9603 // function is blacklisted by AstNode::IsInlineable.
9595 ASSERT(function_state()->outer() == NULL); 9604 ASSERT(function_state()->outer() == NULL);
9596 ASSERT(call->arguments()->length() == 1); 9605 ASSERT(call->arguments()->length() == 1);
9597 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9606 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9598 HValue* index = Pop(); 9607 HValue* index = Pop();
9599 HInstruction* elements = AddInstruction( 9608 HInstruction* elements = AddInstruction(
9600 new(zone()) HArgumentsElements(false)); 9609 new(zone()) HArgumentsElements(false));
9601 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); 9610 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
9602 HInstruction* checked_index = 9611 HInstruction* checked_index = AddBoundsCheck(index, length);
9603 AddInstruction(new(zone()) HBoundsCheck(index, length));
9604 HAccessArgumentsAt* result = 9612 HAccessArgumentsAt* result =
9605 new(zone()) HAccessArgumentsAt(elements, length, checked_index); 9613 new(zone()) HAccessArgumentsAt(elements, length, checked_index);
9606 return ast_context()->ReturnInstruction(result, call->id()); 9614 return ast_context()->ReturnInstruction(result, call->id());
9607 } 9615 }
9608 9616
9609 9617
9610 // Support for accessing the class and value fields of an object. 9618 // Support for accessing the class and value fields of an object.
9611 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { 9619 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) {
9612 // The special form detected by IsClassOfTest is detected before we get here 9620 // The special form detected by IsClassOfTest is detected before we get here
9613 // and does not cause a bailout. 9621 // and does not cause a bailout.
(...skipping 1008 matching lines...) Expand 10 before | Expand all | Expand 10 after
10622 } 10630 }
10623 } 10631 }
10624 10632
10625 #ifdef DEBUG 10633 #ifdef DEBUG
10626 if (graph_ != NULL) graph_->Verify(false); // No full verify. 10634 if (graph_ != NULL) graph_->Verify(false); // No full verify.
10627 if (allocator_ != NULL) allocator_->Verify(); 10635 if (allocator_ != NULL) allocator_->Verify();
10628 #endif 10636 #endif
10629 } 10637 }
10630 10638
10631 } } // namespace v8::internal 10639 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698