Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |