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 |