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 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 |