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

Side by Side Diff: src/hydrogen.cc

Issue 308793012: Inline fast path for Array.indexOf() and Array.lastIndexOf(). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 6 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 | « no previous file | src/objects.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "hydrogen.h" 5 #include "hydrogen.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "v8.h" 9 #include "v8.h"
10 #include "allocation-site-scopes.h" 10 #include "allocation-site-scopes.h"
(...skipping 8014 matching lines...) Expand 10 before | Expand all | Expand 10 after
8025 if_inline.End(); 8025 if_inline.End();
8026 } 8026 }
8027 if_lengthiszero.End(); 8027 if_lengthiszero.End();
8028 } 8028 }
8029 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); 8029 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top();
8030 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 8030 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
8031 if (!ast_context()->IsEffect()) Drop(1); 8031 if (!ast_context()->IsEffect()) Drop(1);
8032 ast_context()->ReturnValue(result); 8032 ast_context()->ReturnValue(result);
8033 return true; 8033 return true;
8034 } 8034 }
8035 case kArrayIndexOf:
8036 case kArrayLastIndexOf: {
8037 if (receiver_map.is_null()) return false;
8038 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
8039 ElementsKind kind = receiver_map->elements_kind();
8040 if (!IsFastElementsKind(kind)) return false;
8041 if (receiver_map->is_observed()) return false;
8042 if (argument_count != 2) return false;
8043 ASSERT(receiver_map->is_extensible());
8044
8045 // If there may be elements accessors in the prototype chain, the fast
8046 // inlined version can't be used.
8047 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false;
8048
8049 // If there currently can be no elements accessors on the prototype chain,
8050 // it doesn't mean that there won't be any later. Install a full prototype
8051 // chain check to trap element accessors being installed on the prototype
8052 // chain, which would cause elements to go to dictionary mode and result
8053 // in a map change.
8054 BuildCheckPrototypeMaps(
8055 handle(JSObject::cast(receiver_map->prototype()), isolate()),
8056 Handle<JSObject>::null());
8057
8058 HValue* search_element = Pop();
8059 HValue* receiver = Pop();
8060 HValue* index;
8061 Drop(1); // Drop function.
8062
8063 {
mvstanton 2014/06/02 11:43:44 How about put this in a function, BuildArrayIndexO
Benedikt Meurer 2014/06/02 12:08:16 Done.
8064 NoObservableSideEffectsScope scope(this);
8065
8066 HValue* elements = AddLoadElements(receiver);
8067 HValue* length = AddLoadArrayLength(receiver, kind);
8068
8069 HValue* initial;
8070 HValue* terminating;
8071 Token::Value token;
8072 LoopBuilder::Direction direction;
8073 if (id == kArrayIndexOf) {
8074 initial = graph()->GetConstant0();
8075 terminating = length;
8076 token = Token::LT;
8077 direction = LoopBuilder::kPostIncrement;
8078 } else {
8079 ASSERT_EQ(kArrayLastIndexOf, id);
8080 initial = length;
8081 terminating = graph()->GetConstant0();
8082 token = Token::GTE;
8083 direction = LoopBuilder::kPreDecrement;
8084 }
8085
8086 if (!ast_context()->IsEffect()) Push(graph()->GetConstantMinus1());
8087 if (IsFastDoubleElementsKind(kind) ||
8088 IsFastSmiElementsKind(kind)) {
8089 LoopBuilder loop(this, context(), direction);
8090 {
8091 index = loop.BeginBody(initial, terminating, token);
8092 HValue* element = AddUncasted<HLoadKeyed>(
8093 elements, index, static_cast<HValue*>(NULL),
8094 kind, ALLOW_RETURN_HOLE);
8095 IfBuilder if_issame(this);
8096 if (IsFastDoubleElementsKind(kind)) {
8097 if_issame.If<HCompareNumericAndBranch>(
8098 element, search_element, Token::EQ_STRICT);
8099 } else {
8100 if_issame.If<HCompareObjectEqAndBranch>(element, search_element);
8101 }
8102 if_issame.Then();
8103 {
8104 if (!ast_context()->IsEffect()) {
8105 Drop(1);
8106 Push(index);
8107 }
8108 loop.Break();
8109 }
8110 if_issame.End();
8111 }
8112 loop.EndBody();
8113 } else {
8114 IfBuilder if_isstring(this);
8115 if_isstring.If<HIsStringAndBranch>(search_element);
8116 if_isstring.Then();
8117 {
8118 LoopBuilder loop(this, context(), direction);
8119 {
8120 index = loop.BeginBody(initial, terminating, token);
8121 HValue* element = AddUncasted<HLoadKeyed>(
8122 elements, index, static_cast<HValue*>(NULL),
8123 kind, ALLOW_RETURN_HOLE);
8124 IfBuilder if_issame(this);
8125 if_issame.If<HIsStringAndBranch>(element);
8126 if_issame.AndIf<HStringCompareAndBranch>(
8127 element, search_element, Token::EQ_STRICT);
8128 if_issame.Then();
8129 {
8130 if (!ast_context()->IsEffect()) {
8131 Drop(1);
8132 Push(index);
8133 }
8134 loop.Break();
8135 }
8136 if_issame.End();
8137 }
8138 loop.EndBody();
8139 }
8140 if_isstring.Else();
8141 {
8142 LoopBuilder loop(this, context(), direction);
8143 {
8144 index = loop.BeginBody(initial, terminating, token);
8145 HValue* element = AddUncasted<HLoadKeyed>(
8146 elements, index, static_cast<HValue*>(NULL),
8147 kind, ALLOW_RETURN_HOLE);
8148 IfBuilder if_issame(this);
8149 if_issame.If<HCompareObjectEqAndBranch>(element, search_element);
8150 if_issame.Then();
8151 {
8152 if (!ast_context()->IsEffect()) {
8153 Drop(1);
8154 Push(index);
8155 }
8156 loop.Break();
8157 }
8158 if_issame.End();
8159 }
8160 loop.EndBody();
8161 }
8162 if_isstring.End();
8163 }
8164 }
mvstanton 2014/06/02 11:43:44 function ends here, postcondition being that in no
8165
8166 index = ast_context()->IsEffect() ? graph()->GetConstant0() : Top();
8167 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
8168 if (!ast_context()->IsEffect()) Drop(1);
8169 ast_context()->ReturnValue(index);
8170 return true;
8171 }
8035 default: 8172 default:
8036 // Not yet supported for inlining. 8173 // Not yet supported for inlining.
8037 break; 8174 break;
8038 } 8175 }
8039 return false; 8176 return false;
8040 } 8177 }
8041 8178
8042 8179
8043 bool HOptimizedGraphBuilder::TryInlineApiFunctionCall(Call* expr, 8180 bool HOptimizedGraphBuilder::TryInlineApiFunctionCall(Call* expr,
8044 HValue* receiver) { 8181 HValue* receiver) {
(...skipping 3831 matching lines...) Expand 10 before | Expand all | Expand 10 after
11876 if (ShouldProduceTraceOutput()) { 12013 if (ShouldProduceTraceOutput()) {
11877 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12014 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11878 } 12015 }
11879 12016
11880 #ifdef DEBUG 12017 #ifdef DEBUG
11881 graph_->Verify(false); // No full verify. 12018 graph_->Verify(false); // No full verify.
11882 #endif 12019 #endif
11883 } 12020 }
11884 12021
11885 } } // namespace v8::internal 12022 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698