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

Side by Side Diff: src/hydrogen.cc

Issue 308793010: Inline Array.shift() fast path instead of using a code stub. (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 | « src/code-stubs-hydrogen.cc ('k') | src/hydrogen-instructions.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 7922 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
OLDNEW
« no previous file with comments | « src/code-stubs-hydrogen.cc ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698