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 7922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7933 | 7933 |
7934 // If there currently can be no elements accessors on the prototype chain, | 7934 // If there currently can be no elements accessors on the prototype chain, |
7935 // it doesn't mean that there won't be any later. Install a full prototype | 7935 // it doesn't mean that there won't be any later. Install a full prototype |
7936 // chain check to trap element accessors being installed on the prototype | 7936 // chain check to trap element accessors being installed on the prototype |
7937 // chain, which would cause elements to go to dictionary mode and result | 7937 // chain, which would cause elements to go to dictionary mode and result |
7938 // in a map change. | 7938 // in a map change. |
7939 BuildCheckPrototypeMaps( | 7939 BuildCheckPrototypeMaps( |
7940 handle(JSObject::cast(receiver_map->prototype()), isolate()), | 7940 handle(JSObject::cast(receiver_map->prototype()), isolate()), |
7941 Handle<JSObject>::null()); | 7941 Handle<JSObject>::null()); |
7942 | 7942 |
7943 // Threshold for fast inlined Array.shift(). | |
7944 HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16)); | |
7945 | |
7943 Drop(expr->arguments()->length()); | 7946 Drop(expr->arguments()->length()); |
7944 HValue* receiver = Pop(); | 7947 HValue* receiver = Pop(); |
7945 Drop(1); // function | 7948 HValue* function = Pop(); |
7949 HValue* result; | |
7946 | 7950 |
7947 receiver = AddCheckMap(receiver, receiver_map); | 7951 { |
Yang
2014/06/02 06:57:01
Could we have a BuildArrayShift instead of having
Benedikt Meurer
2014/06/02 07:02:12
As discussed offline: Leaving it here for consiste
| |
7948 HInstruction* result = NewUncasted<HArrayShift>(receiver, kind); | 7952 NoObservableSideEffectsScope scope(this); |
7949 ast_context()->ReturnInstruction(result, expr->id()); | 7953 |
7954 HValue* length = Add<HLoadNamedField>( | |
7955 receiver, static_cast<HValue*>(NULL), | |
7956 HObjectAccess::ForArrayLength(kind)); | |
7957 | |
7958 IfBuilder if_lengthiszero(this); | |
7959 HValue* lengthiszero = if_lengthiszero.If<HCompareNumericAndBranch>( | |
7960 length, graph()->GetConstant0(), Token::EQ); | |
7961 if_lengthiszero.Then(); | |
7962 { | |
7963 if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined()); | |
7964 } | |
7965 if_lengthiszero.Else(); | |
7966 { | |
7967 HValue* elements = AddLoadElements(receiver); | |
7968 | |
7969 // Check if we can use the fast inlined Array.shift(). | |
7970 IfBuilder if_inline(this); | |
7971 if_inline.If<HCompareNumericAndBranch>( | |
7972 length, inline_threshold, Token::LTE); | |
7973 if (IsFastSmiOrObjectElementsKind(kind)) { | |
7974 // We cannot handle copy-on-write backing stores here. | |
7975 if_inline.AndIf<HCompareMap>( | |
7976 elements, isolate()->factory()->fixed_array_map()); | |
7977 } | |
7978 if_inline.Then(); | |
7979 { | |
7980 // Remember the result. | |
7981 if (!ast_context()->IsEffect()) { | |
7982 Push(AddElementAccess(elements, graph()->GetConstant0(), NULL, | |
7983 lengthiszero, kind, LOAD)); | |
7984 } | |
7985 | |
7986 // Compute the new length. | |
7987 HValue* new_length = AddUncasted<HSub>( | |
7988 length, graph()->GetConstant1()); | |
7989 new_length->ClearFlag(HValue::kCanOverflow); | |
7990 | |
7991 // Copy the remaining elements. | |
7992 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); | |
7993 { | |
7994 HValue* new_key = loop.BeginBody( | |
7995 graph()->GetConstant0(), new_length, Token::LT); | |
7996 HValue* key = AddUncasted<HAdd>(new_key, graph()->GetConstant1()); | |
7997 key->ClearFlag(HValue::kCanOverflow); | |
7998 HValue* element = AddUncasted<HLoadKeyed>( | |
7999 elements, key, lengthiszero, kind, ALLOW_RETURN_HOLE); | |
8000 HStoreKeyed* store = Add<HStoreKeyed>( | |
8001 elements, new_key, element, kind); | |
8002 store->SetFlag(HValue::kAllowUndefinedAsNaN); | |
8003 } | |
8004 loop.EndBody(); | |
8005 | |
8006 // Put a hole at the end. | |
8007 HValue* hole = IsFastSmiOrObjectElementsKind(kind) | |
8008 ? Add<HConstant>(isolate()->factory()->the_hole_value()) | |
8009 : Add<HConstant>(FixedDoubleArray::hole_nan_as_double()); | |
8010 if (IsFastSmiOrObjectElementsKind(kind)) kind = FAST_HOLEY_ELEMENTS; | |
8011 Add<HStoreKeyed>( | |
8012 elements, new_length, hole, kind, INITIALIZING_STORE); | |
8013 | |
8014 // Remember new length. | |
8015 Add<HStoreNamedField>( | |
8016 receiver, HObjectAccess::ForArrayLength(kind), | |
8017 new_length, STORE_TO_INITIALIZED_ENTRY); | |
8018 } | |
8019 if_inline.Else(); | |
8020 { | |
8021 Add<HPushArguments>(receiver); | |
8022 result = Add<HCallJSFunction>(function, 1, true); | |
8023 if (!ast_context()->IsEffect()) Push(result); | |
8024 } | |
8025 if_inline.End(); | |
8026 } | |
8027 if_lengthiszero.End(); | |
8028 } | |
8029 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); | |
8030 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | |
8031 if (!ast_context()->IsEffect()) Drop(1); | |
8032 ast_context()->ReturnValue(result); | |
7950 return true; | 8033 return true; |
7951 } | 8034 } |
7952 default: | 8035 default: |
7953 // Not yet supported for inlining. | 8036 // Not yet supported for inlining. |
7954 break; | 8037 break; |
7955 } | 8038 } |
7956 return false; | 8039 return false; |
7957 } | 8040 } |
7958 | 8041 |
7959 | 8042 |
(...skipping 3833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11793 if (ShouldProduceTraceOutput()) { | 11876 if (ShouldProduceTraceOutput()) { |
11794 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11877 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
11795 } | 11878 } |
11796 | 11879 |
11797 #ifdef DEBUG | 11880 #ifdef DEBUG |
11798 graph_->Verify(false); // No full verify. | 11881 graph_->Verify(false); // No full verify. |
11799 #endif | 11882 #endif |
11800 } | 11883 } |
11801 | 11884 |
11802 } } // namespace v8::internal | 11885 } } // namespace v8::internal |
OLD | NEW |