Chromium Code Reviews

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: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
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 900 matching lines...)
911 if (is_store && (fast_elements || fast_smi_only_elements)) { 911 if (is_store && (fast_elements || fast_smi_only_elements)) {
912 HCheckMaps* check_cow_map = new(zone) HCheckMaps( 912 HCheckMaps* check_cow_map = new(zone) HCheckMaps(
913 elements, Isolate::Current()->factory()->fixed_array_map(), zone); 913 elements, Isolate::Current()->factory()->fixed_array_map(), zone);
914 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 914 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
915 AddInstruction(check_cow_map); 915 AddInstruction(check_cow_map);
916 } 916 }
917 HInstruction* length = NULL; 917 HInstruction* length = NULL;
918 HInstruction* checked_key = NULL; 918 HInstruction* checked_key = NULL;
919 if (IsExternalArrayElementsKind(elements_kind)) { 919 if (IsExternalArrayElementsKind(elements_kind)) {
920 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); 920 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements));
921 checked_key = AddInstruction(new(zone) HBoundsCheck( 921 checked_key = HBoundsCheck::AddToGraph(
922 key, length, ALLOW_SMI_KEY, checked_index_representation)); 922 this, key, length, ALLOW_SMI_KEY, checked_index_representation);
923 HLoadExternalArrayPointer* external_elements = 923 HLoadExternalArrayPointer* external_elements =
924 new(zone) HLoadExternalArrayPointer(elements); 924 new(zone) HLoadExternalArrayPointer(elements);
925 AddInstruction(external_elements); 925 AddInstruction(external_elements);
926 return BuildExternalArrayElementAccess( 926 return BuildExternalArrayElementAccess(
927 external_elements, checked_key, val, mapcheck, 927 external_elements, checked_key, val, mapcheck,
928 elements_kind, is_store); 928 elements_kind, is_store);
929 } 929 }
930 ASSERT(fast_smi_only_elements || 930 ASSERT(fast_smi_only_elements ||
931 fast_elements || 931 fast_elements ||
932 IsFastDoubleElementsKind(elements_kind)); 932 IsFastDoubleElementsKind(elements_kind));
933 if (is_js_array) { 933 if (is_js_array) {
934 length = AddInstruction(new(zone) HJSArrayLength(object, mapcheck, 934 length = AddInstruction(new(zone) HJSArrayLength(object, mapcheck,
935 HType::Smi())); 935 HType::Smi()));
936 } else { 936 } else {
937 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); 937 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements));
938 } 938 }
939 checked_key = AddInstruction(new(zone) HBoundsCheck( 939 checked_key = HBoundsCheck::AddToGraph(
940 key, length, ALLOW_SMI_KEY, checked_index_representation)); 940 this, key, length, ALLOW_SMI_KEY, checked_index_representation);
941 return BuildFastElementAccess(elements, checked_key, val, mapcheck, 941 return BuildFastElementAccess(elements, checked_key, val, mapcheck,
942 elements_kind, is_store); 942 elements_kind, is_store);
943 } 943 }
944 944
945 945
946 HValue* HGraphBuilder::BuildAllocateElements(HContext* context, 946 HValue* HGraphBuilder::BuildAllocateElements(HContext* context,
947 ElementsKind kind, 947 ElementsKind kind,
948 HValue* capacity) { 948 HValue* capacity) {
949 Zone* zone = this->zone(); 949 Zone* zone = this->zone();
950 950
(...skipping 5875 matching lines...)
6826 elements_kind <= LAST_ELEMENTS_KIND; 6826 elements_kind <= LAST_ELEMENTS_KIND;
6827 elements_kind = ElementsKind(elements_kind + 1)) { 6827 elements_kind = ElementsKind(elements_kind + 1)) {
6828 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some 6828 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some
6829 // code that's executed for all external array cases. 6829 // code that's executed for all external array cases.
6830 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == 6830 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND ==
6831 LAST_ELEMENTS_KIND); 6831 LAST_ELEMENTS_KIND);
6832 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND 6832 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND
6833 && todo_external_array) { 6833 && todo_external_array) {
6834 HInstruction* length = 6834 HInstruction* length =
6835 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); 6835 AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
6836 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 6836 checked_key = HBoundsCheck::AddToGraph(this, key, length);
6837 external_elements = new(zone()) HLoadExternalArrayPointer(elements); 6837 external_elements = new(zone()) HLoadExternalArrayPointer(elements);
6838 AddInstruction(external_elements); 6838 AddInstruction(external_elements);
6839 } 6839 }
6840 if (type_todo[elements_kind]) { 6840 if (type_todo[elements_kind]) {
6841 HBasicBlock* if_true = graph()->CreateBasicBlock(); 6841 HBasicBlock* if_true = graph()->CreateBasicBlock();
6842 HBasicBlock* if_false = graph()->CreateBasicBlock(); 6842 HBasicBlock* if_false = graph()->CreateBasicBlock();
6843 HCompareConstantEqAndBranch* elements_kind_branch = 6843 HCompareConstantEqAndBranch* elements_kind_branch =
6844 new(zone()) HCompareConstantEqAndBranch( 6844 new(zone()) HCompareConstantEqAndBranch(
6845 elements_kind_instr, elements_kind, Token::EQ_STRICT); 6845 elements_kind_instr, elements_kind, Token::EQ_STRICT);
6846 elements_kind_branch->SetSuccessorAt(0, if_true); 6846 elements_kind_branch->SetSuccessorAt(0, if_true);
(...skipping 21 matching lines...)
6868 HHasInstanceTypeAndBranch* typecheck = 6868 HHasInstanceTypeAndBranch* typecheck =
6869 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); 6869 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE);
6870 typecheck->SetSuccessorAt(0, if_jsarray); 6870 typecheck->SetSuccessorAt(0, if_jsarray);
6871 typecheck->SetSuccessorAt(1, if_fastobject); 6871 typecheck->SetSuccessorAt(1, if_fastobject);
6872 current_block()->Finish(typecheck); 6872 current_block()->Finish(typecheck);
6873 6873
6874 set_current_block(if_jsarray); 6874 set_current_block(if_jsarray);
6875 HInstruction* length; 6875 HInstruction* length;
6876 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck, 6876 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck,
6877 HType::Smi())); 6877 HType::Smi()));
6878 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, 6878 checked_key = HBoundsCheck::AddToGraph(this, key, length,
6879 ALLOW_SMI_KEY)); 6879 ALLOW_SMI_KEY);
6880 access = AddInstruction(BuildFastElementAccess( 6880 access = AddInstruction(BuildFastElementAccess(
6881 elements, checked_key, val, elements_kind_branch, 6881 elements, checked_key, val, elements_kind_branch,
6882 elements_kind, is_store)); 6882 elements_kind, is_store));
6883 if (!is_store) { 6883 if (!is_store) {
6884 Push(access); 6884 Push(access);
6885 } 6885 }
6886 6886
6887 *has_side_effects |= access->HasObservableSideEffects(); 6887 *has_side_effects |= access->HasObservableSideEffects();
6888 if (position != -1) { 6888 if (position != -1) {
6889 access->set_position(position); 6889 access->set_position(position);
6890 } 6890 }
6891 if_jsarray->Goto(join); 6891 if_jsarray->Goto(join);
6892 6892
6893 set_current_block(if_fastobject); 6893 set_current_block(if_fastobject);
6894 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); 6894 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
6895 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, 6895 checked_key = HBoundsCheck::AddToGraph(this, key, length,
6896 ALLOW_SMI_KEY)); 6896 ALLOW_SMI_KEY);
6897 access = AddInstruction(BuildFastElementAccess( 6897 access = AddInstruction(BuildFastElementAccess(
6898 elements, checked_key, val, elements_kind_branch, 6898 elements, checked_key, val, elements_kind_branch,
6899 elements_kind, is_store)); 6899 elements_kind, is_store));
6900 } else if (elements_kind == DICTIONARY_ELEMENTS) { 6900 } else if (elements_kind == DICTIONARY_ELEMENTS) {
6901 if (is_store) { 6901 if (is_store) {
6902 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); 6902 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val));
6903 } else { 6903 } else {
6904 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); 6904 access = AddInstruction(BuildLoadKeyedGeneric(object, key));
6905 } 6905 }
6906 } else { // External array elements. 6906 } else { // External array elements.
(...skipping 128 matching lines...)
7035 Push(graph()->GetArgumentsObject()); 7035 Push(graph()->GetArgumentsObject());
7036 VisitForValue(expr->key()); 7036 VisitForValue(expr->key());
7037 if (HasStackOverflow() || current_block() == NULL) return true; 7037 if (HasStackOverflow() || current_block() == NULL) return true;
7038 HValue* key = Pop(); 7038 HValue* key = Pop();
7039 Drop(1); // Arguments object. 7039 Drop(1); // Arguments object.
7040 if (function_state()->outer() == NULL) { 7040 if (function_state()->outer() == NULL) {
7041 HInstruction* elements = AddInstruction( 7041 HInstruction* elements = AddInstruction(
7042 new(zone()) HArgumentsElements(false)); 7042 new(zone()) HArgumentsElements(false));
7043 HInstruction* length = AddInstruction( 7043 HInstruction* length = AddInstruction(
7044 new(zone()) HArgumentsLength(elements)); 7044 new(zone()) HArgumentsLength(elements));
7045 HInstruction* checked_key = 7045 HInstruction* checked_key = HBoundsCheck::AddToGraph(this, key, length);
7046 AddInstruction(new(zone()) HBoundsCheck(key, length));
7047 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); 7046 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key);
7048 } else { 7047 } else {
7049 EnsureArgumentsArePushedForAccess(); 7048 EnsureArgumentsArePushedForAccess();
7050 7049
7051 // Number of arguments without receiver. 7050 // Number of arguments without receiver.
7052 HInstruction* elements = function_state()->arguments_elements(); 7051 HInstruction* elements = function_state()->arguments_elements();
7053 int argument_count = environment()-> 7052 int argument_count = environment()->
7054 arguments_environment()->parameter_count() - 1; 7053 arguments_environment()->parameter_count() - 1;
7055 HInstruction* length = AddInstruction(new(zone()) HConstant( 7054 HInstruction* length = AddInstruction(new(zone()) HConstant(
7056 Handle<Object>(Smi::FromInt(argument_count)), 7055 Handle<Object>(Smi::FromInt(argument_count)),
7057 Representation::Integer32())); 7056 Representation::Integer32()));
7058 HInstruction* checked_key = 7057 HInstruction* checked_key = HBoundsCheck::AddToGraph(this, key, length);
7059 AddInstruction(new(zone()) HBoundsCheck(key, length));
7060 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); 7058 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key);
7061 } 7059 }
7062 } 7060 }
7063 ast_context()->ReturnInstruction(result, expr->id()); 7061 ast_context()->ReturnInstruction(result, expr->id());
7064 return true; 7062 return true;
7065 } 7063 }
7066 7064
7067 7065
7068 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { 7066 void HOptimizedGraphBuilder::VisitProperty(Property* expr) {
7069 ASSERT(!HasStackOverflow()); 7067 ASSERT(!HasStackOverflow());
(...skipping 1693 matching lines...)
8763 8761
8764 8762
8765 HStringCharCodeAt* HOptimizedGraphBuilder::BuildStringCharCodeAt( 8763 HStringCharCodeAt* HOptimizedGraphBuilder::BuildStringCharCodeAt(
8766 HValue* context, 8764 HValue* context,
8767 HValue* string, 8765 HValue* string,
8768 HValue* index) { 8766 HValue* index) {
8769 AddInstruction(new(zone()) HCheckNonSmi(string)); 8767 AddInstruction(new(zone()) HCheckNonSmi(string));
8770 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 8768 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
8771 HStringLength* length = new(zone()) HStringLength(string); 8769 HStringLength* length = new(zone()) HStringLength(string);
8772 AddInstruction(length); 8770 AddInstruction(length);
8773 HInstruction* checked_index = 8771 HInstruction* checked_index = HBoundsCheck::AddToGraph(this, index, length);
8774 AddInstruction(new(zone()) HBoundsCheck(index, length));
8775 return new(zone()) HStringCharCodeAt(context, string, checked_index); 8772 return new(zone()) HStringCharCodeAt(context, string, checked_index);
8776 } 8773 }
8777 8774
8778 // Checks if the given shift amounts have form: (sa) and (32 - sa). 8775 // Checks if the given shift amounts have form: (sa) and (32 - sa).
8779 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, 8776 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
8780 HValue* const32_minus_sa) { 8777 HValue* const32_minus_sa) {
8781 if (!const32_minus_sa->IsSub()) return false; 8778 if (!const32_minus_sa->IsSub()) return false;
8782 HSub* sub = HSub::cast(const32_minus_sa); 8779 HSub* sub = HSub::cast(const32_minus_sa);
8783 if (sa != sub->right()) return false; 8780 if (sa != sub->right()) return false;
8784 HValue* const32 = sub->left(); 8781 HValue* const32 = sub->left();
(...skipping 807 matching lines...)
9592 // Our implementation of arguments (based on this stack frame or an 9589 // Our implementation of arguments (based on this stack frame or an
9593 // adapter below it) does not work for inlined functions. This runtime 9590 // adapter below it) does not work for inlined functions. This runtime
9594 // function is blacklisted by AstNode::IsInlineable. 9591 // function is blacklisted by AstNode::IsInlineable.
9595 ASSERT(function_state()->outer() == NULL); 9592 ASSERT(function_state()->outer() == NULL);
9596 ASSERT(call->arguments()->length() == 1); 9593 ASSERT(call->arguments()->length() == 1);
9597 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9594 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9598 HValue* index = Pop(); 9595 HValue* index = Pop();
9599 HInstruction* elements = AddInstruction( 9596 HInstruction* elements = AddInstruction(
9600 new(zone()) HArgumentsElements(false)); 9597 new(zone()) HArgumentsElements(false));
9601 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); 9598 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
9602 HInstruction* checked_index = 9599 HInstruction* checked_index = HBoundsCheck::AddToGraph(this, index, length);
9603 AddInstruction(new(zone()) HBoundsCheck(index, length));
9604 HAccessArgumentsAt* result = 9600 HAccessArgumentsAt* result =
9605 new(zone()) HAccessArgumentsAt(elements, length, checked_index); 9601 new(zone()) HAccessArgumentsAt(elements, length, checked_index);
9606 return ast_context()->ReturnInstruction(result, call->id()); 9602 return ast_context()->ReturnInstruction(result, call->id());
9607 } 9603 }
9608 9604
9609 9605
9610 // Support for accessing the class and value fields of an object. 9606 // Support for accessing the class and value fields of an object.
9611 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { 9607 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) {
9612 // The special form detected by IsClassOfTest is detected before we get here 9608 // The special form detected by IsClassOfTest is detected before we get here
9613 // and does not cause a bailout. 9609 // and does not cause a bailout.
(...skipping 1008 matching lines...)
10622 } 10618 }
10623 } 10619 }
10624 10620
10625 #ifdef DEBUG 10621 #ifdef DEBUG
10626 if (graph_ != NULL) graph_->Verify(false); // No full verify. 10622 if (graph_ != NULL) graph_->Verify(false); // No full verify.
10627 if (allocator_ != NULL) allocator_->Verify(); 10623 if (allocator_ != NULL) allocator_->Verify();
10628 #endif 10624 #endif
10629 } 10625 }
10630 10626
10631 } } // namespace v8::internal 10627 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine