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

Side by Side Diff: src/runtime.cc

Issue 397593008: Keep new arrays allocated with 'new Array(N)' in fast mode (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix slow test Created 6 years, 4 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/runtime.h ('k') | test/fuzz-natives/base.js » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 <stdlib.h> 5 #include <stdlib.h>
6 #include <limits> 6 #include <limits>
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/accessors.h" 10 #include "src/accessors.h"
(...skipping 10558 matching lines...) Expand 10 before | Expand all | Expand 10 after
10569 // Returns an array that tells you where in the [0, length) interval an array 10569 // Returns an array that tells you where in the [0, length) interval an array
10570 // might have elements. Can either return an array of keys (positive integers 10570 // might have elements. Can either return an array of keys (positive integers
10571 // or undefined) or a number representing the positive length of an interval 10571 // or undefined) or a number representing the positive length of an interval
10572 // starting at index 0. 10572 // starting at index 0.
10573 // Intervals can span over some keys that are not in the object. 10573 // Intervals can span over some keys that are not in the object.
10574 RUNTIME_FUNCTION(Runtime_GetArrayKeys) { 10574 RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
10575 HandleScope scope(isolate); 10575 HandleScope scope(isolate);
10576 ASSERT(args.length() == 2); 10576 ASSERT(args.length() == 2);
10577 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); 10577 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
10578 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); 10578 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
10579 if (array->elements()->IsDictionary()) { 10579
10580 ElementsKind kind = array->GetElementsKind();
10581 bool estimate_keys_as_length = IsFastPackedElementsKind(kind);
10582 if (IsHoleyElementsKind(kind)) {
10583 ElementsAccessor* accessor = array->GetElementsAccessor();
10584 // If more than 10% of the array is holes, then calculate the key set, it's
10585 // much faster than using the runtime to walk the prototype chain in the
10586 // hole case.
10587 int holes = 0;
10588 int length = array->elements()->length();
10589 for (int i = 0; i < length; ++i) {
10590 if (!accessor->HasElement(array, array, i)) {
10591 ++holes;
10592 }
10593 }
10594 estimate_keys_as_length = holes < static_cast<int>(length / 10);
10595 }
10596
10597 if (estimate_keys_as_length) {
10598 RUNTIME_ASSERT(array->HasFastSmiOrObjectElements() ||
10599 array->HasFastDoubleElements());
10600 uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
10601 return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
10602 } else {
10580 Handle<FixedArray> keys = isolate->factory()->empty_fixed_array(); 10603 Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
10581 for (PrototypeIterator iter(isolate, array, 10604 for (PrototypeIterator iter(isolate, array,
10582 PrototypeIterator::START_AT_RECEIVER); 10605 PrototypeIterator::START_AT_RECEIVER);
10583 !iter.IsAtEnd(); iter.Advance()) { 10606 !iter.IsAtEnd(); iter.Advance()) {
10584 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy() || 10607 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy() ||
10585 JSObject::cast(*PrototypeIterator::GetCurrent(iter)) 10608 JSObject::cast(*PrototypeIterator::GetCurrent(iter))
10586 ->HasIndexedInterceptor()) { 10609 ->HasIndexedInterceptor()) {
10587 // Bail out if we find a proxy or interceptor, likely not worth 10610 // Bail out if we find a proxy or interceptor, likely not worth
10588 // collecting keys in that case. 10611 // collecting keys in that case.
10589 return *isolate->factory()->NewNumberFromUint(length); 10612 return *isolate->factory()->NewNumberFromUint(length);
10590 } 10613 }
10591 Handle<JSObject> current = 10614 Handle<JSObject> current =
10592 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 10615 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
10593 Handle<FixedArray> current_keys = 10616 Handle<FixedArray> current_keys =
10594 isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE)); 10617 isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE));
10595 current->GetOwnElementKeys(*current_keys, NONE); 10618 current->GetOwnElementKeys(*current_keys, NONE);
10596 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 10619 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
10597 isolate, keys, FixedArray::UnionOfKeys(keys, current_keys)); 10620 isolate, keys, FixedArray::UnionOfKeys(keys, current_keys));
10598 } 10621 }
10599 // Erase any keys >= length. 10622 // Erase any keys >= length.
10600 // TODO(adamk): Remove this step when the contract of %GetArrayKeys 10623 // TODO(adamk): Remove this step when the contract of %GetArrayKeys
10601 // is changed to let this happen on the JS side. 10624 // is changed to let this happen on the JS side.
10602 for (int i = 0; i < keys->length(); i++) { 10625 for (int i = 0; i < keys->length(); i++) {
10603 if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i); 10626 if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
10604 } 10627 }
10605 return *isolate->factory()->NewJSArrayWithElements(keys); 10628 return *isolate->factory()->NewJSArrayWithElements(keys);
10606 } else {
10607 RUNTIME_ASSERT(array->HasFastSmiOrObjectElements() ||
10608 array->HasFastDoubleElements());
10609 uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
10610 return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
10611 } 10629 }
10612 } 10630 }
10613 10631
10614 10632
10615 RUNTIME_FUNCTION(Runtime_LookupAccessor) { 10633 RUNTIME_FUNCTION(Runtime_LookupAccessor) {
10616 HandleScope scope(isolate); 10634 HandleScope scope(isolate);
10617 ASSERT(args.length() == 3); 10635 ASSERT(args.length() == 3);
10618 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); 10636 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
10619 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); 10637 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
10620 CONVERT_SMI_ARG_CHECKED(flag, 2); 10638 CONVERT_SMI_ARG_CHECKED(flag, 2);
(...skipping 4303 matching lines...) Expand 10 before | Expand all | Expand 10 after
14924 ASSERT(arg_count == caller_args->length()); 14942 ASSERT(arg_count == caller_args->length());
14925 } 14943 }
14926 #endif 14944 #endif
14927 return ArrayConstructorCommon(isolate, 14945 return ArrayConstructorCommon(isolate,
14928 constructor, 14946 constructor,
14929 Handle<AllocationSite>::null(), 14947 Handle<AllocationSite>::null(),
14930 caller_args); 14948 caller_args);
14931 } 14949 }
14932 14950
14933 14951
14952 RUNTIME_FUNCTION(Runtime_NormalizeElements) {
14953 HandleScope scope(isolate);
14954 ASSERT(args.length() == 1);
14955 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
14956 JSObject::NormalizeElements(array);
14957 return *array;
14958 }
14959
14960
14934 RUNTIME_FUNCTION(Runtime_MaxSmi) { 14961 RUNTIME_FUNCTION(Runtime_MaxSmi) {
14935 ASSERT(args.length() == 0); 14962 ASSERT(args.length() == 0);
14936 return Smi::FromInt(Smi::kMaxValue); 14963 return Smi::FromInt(Smi::kMaxValue);
14937 } 14964 }
14938 14965
14939 14966
14940 // ---------------------------------------------------------------------------- 14967 // ----------------------------------------------------------------------------
14941 // Implementation of Runtime 14968 // Implementation of Runtime
14942 14969
14943 #define F(name, number_of_args, result_size) \ 14970 #define F(name, number_of_args, result_size) \
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
14995 } 15022 }
14996 return NULL; 15023 return NULL;
14997 } 15024 }
14998 15025
14999 15026
15000 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { 15027 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
15001 return &(kIntrinsicFunctions[static_cast<int>(id)]); 15028 return &(kIntrinsicFunctions[static_cast<int>(id)]);
15002 } 15029 }
15003 15030
15004 } } // namespace v8::internal 15031 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | test/fuzz-natives/base.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698