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

Side by Side Diff: src/objects.cc

Issue 1159433003: Use GetProperty for getting elements. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 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
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 <iomanip> 5 #include <iomanip>
6 #include <sstream> 6 #include <sstream>
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 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 auto curr = PrototypeIterator::GetCurrent(iter); 599 auto curr = PrototypeIterator::GetCurrent(iter);
600 if (!curr->IsJSObject()) break; 600 if (!curr->IsJSObject()) break;
601 auto obj = Handle<JSObject>::cast(curr); 601 auto obj = Handle<JSObject>::cast(curr);
602 if (!obj->HasIndexedInterceptor()) continue; 602 if (!obj->HasIndexedInterceptor()) continue;
603 if (obj->GetIndexedInterceptor()->all_can_read()) return obj; 603 if (obj->GetIndexedInterceptor()->all_can_read()) return obj;
604 } 604 }
605 return MaybeHandle<JSObject>(); 605 return MaybeHandle<JSObject>();
606 } 606 }
607 607
608 608
609 MaybeHandle<Object> JSObject::GetElementWithFailedAccessCheck(
610 Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver,
611 uint32_t index) {
612 Handle<JSObject> holder = object;
613 PrototypeIterator::WhereToStart where_to_start =
614 PrototypeIterator::START_AT_RECEIVER;
615 while (true) {
616 auto all_can_read_holder =
617 FindIndexedAllCanReadHolder(isolate, holder, where_to_start);
618 if (!all_can_read_holder.ToHandle(&holder)) break;
619 auto result =
620 JSObject::GetElementWithInterceptor(holder, receiver, index, false);
621 if (isolate->has_scheduled_exception()) break;
622 if (!result.is_null()) return result;
623 where_to_start = PrototypeIterator::START_AT_PROTOTYPE;
624 }
625 isolate->ReportFailedAccessCheck(object);
626 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
627 return isolate->factory()->undefined_value();
628 }
629
630
631 Maybe<PropertyAttributes> JSObject::GetElementAttributesWithFailedAccessCheck( 609 Maybe<PropertyAttributes> JSObject::GetElementAttributesWithFailedAccessCheck(
632 Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver, 610 Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver,
633 uint32_t index) { 611 uint32_t index) {
634 Handle<JSObject> holder = object; 612 Handle<JSObject> holder = object;
635 PrototypeIterator::WhereToStart where_to_start = 613 PrototypeIterator::WhereToStart where_to_start =
636 PrototypeIterator::START_AT_RECEIVER; 614 PrototypeIterator::START_AT_RECEIVER;
637 while (true) { 615 while (true) {
638 auto all_can_read_holder = 616 auto all_can_read_holder =
639 FindIndexedAllCanReadHolder(isolate, holder, where_to_start); 617 FindIndexedAllCanReadHolder(isolate, holder, where_to_start);
640 if (!all_can_read_holder.ToHandle(&holder)) break; 618 if (!all_can_read_holder.ToHandle(&holder)) break;
641 auto result = 619 auto result =
642 JSObject::GetElementAttributeFromInterceptor(holder, receiver, index); 620 JSObject::GetElementAttributeFromInterceptor(holder, receiver, index);
643 if (isolate->has_scheduled_exception()) break; 621 if (isolate->has_scheduled_exception()) break;
644 if (result.IsJust() && result.FromJust() != ABSENT) return result; 622 if (result.IsJust() && result.FromJust() != ABSENT) return result;
645 where_to_start = PrototypeIterator::START_AT_PROTOTYPE; 623 where_to_start = PrototypeIterator::START_AT_PROTOTYPE;
646 } 624 }
647 isolate->ReportFailedAccessCheck(object); 625 isolate->ReportFailedAccessCheck(object);
648 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>()); 626 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>());
649 return Just(ABSENT); 627 return Just(ABSENT);
650 } 628 }
651 629
652 630
653 MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate,
654 Handle<Object> object,
655 Handle<Object> receiver,
656 uint32_t index) {
657 DCHECK(!object->IsUndefined());
658
659 // Iterate up the prototype chain until an element is found or the null
660 // prototype is encountered.
661 for (PrototypeIterator iter(isolate, object,
662 object->IsJSProxy() || object->IsJSObject()
663 ? PrototypeIterator::START_AT_RECEIVER
664 : PrototypeIterator::START_AT_PROTOTYPE);
665 !iter.IsAtEnd(); iter.Advance()) {
666 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
667 return JSProxy::GetElementWithHandler(
668 Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), receiver,
669 index);
670 }
671
672 // Inline the case for JSObjects. Doing so significantly improves the
673 // performance of fetching elements where checking the prototype chain is
674 // necessary.
675 Handle<JSObject> js_object =
676 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
677
678 // Check access rights if needed.
679 if (js_object->IsAccessCheckNeeded()) {
680 if (!isolate->MayAccess(js_object)) {
681 return JSObject::GetElementWithFailedAccessCheck(isolate, js_object,
682 receiver, index);
683 }
684 }
685
686 if (js_object->HasIndexedInterceptor()) {
687 return JSObject::GetElementWithInterceptor(js_object, receiver, index,
688 true);
689 }
690
691 if (js_object->elements() != isolate->heap()->empty_fixed_array()) {
692 Handle<Object> result;
693 ASSIGN_RETURN_ON_EXCEPTION(
694 isolate, result,
695 js_object->GetElementsAccessor()->Get(receiver, js_object, index),
696 Object);
697 if (!result->IsTheHole()) return result;
698 }
699 }
700
701 return isolate->factory()->undefined_value();
702 }
703
704
705 MaybeHandle<Object> Object::SetElementWithReceiver( 631 MaybeHandle<Object> Object::SetElementWithReceiver(
706 Isolate* isolate, Handle<Object> object, Handle<Object> receiver, 632 Isolate* isolate, Handle<Object> object, Handle<Object> receiver,
707 uint32_t index, Handle<Object> value, LanguageMode language_mode) { 633 uint32_t index, Handle<Object> value, LanguageMode language_mode) {
708 // Iterate up the prototype chain until an element is found or the null 634 // Iterate up the prototype chain until an element is found or the null
709 // prototype is encountered. 635 // prototype is encountered.
710 bool done = false; 636 bool done = false;
711 for (PrototypeIterator iter(isolate, object, 637 for (PrototypeIterator iter(isolate, object,
712 object->IsJSProxy() || object->IsJSObject() 638 object->IsJSProxy() || object->IsJSObject()
713 ? PrototypeIterator::START_AT_RECEIVER 639 ? PrototypeIterator::START_AT_RECEIVER
714 : PrototypeIterator::START_AT_PROTOTYPE); 640 : PrototypeIterator::START_AT_PROTOTYPE);
(...skipping 7493 matching lines...) Expand 10 before | Expand all | Expand 10 after
8208 GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( 8134 GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
8209 this, length() - new_length); 8135 this, length() - new_length);
8210 } 8136 }
8211 } 8137 }
8212 8138
8213 8139
8214 MaybeHandle<FixedArray> FixedArray::AddKeysFromArrayLike( 8140 MaybeHandle<FixedArray> FixedArray::AddKeysFromArrayLike(
8215 Handle<FixedArray> content, Handle<JSObject> array, KeyFilter filter) { 8141 Handle<FixedArray> content, Handle<JSObject> array, KeyFilter filter) {
8216 DCHECK(array->IsJSArray() || array->HasSloppyArgumentsElements()); 8142 DCHECK(array->IsJSArray() || array->HasSloppyArgumentsElements());
8217 ElementsAccessor* accessor = array->GetElementsAccessor(); 8143 ElementsAccessor* accessor = array->GetElementsAccessor();
8218 Handle<FixedArray> result; 8144 Handle<FixedArray> result =
8219 ASSIGN_RETURN_ON_EXCEPTION( 8145 accessor->AddElementsToFixedArray(array, content, filter);
8220 array->GetIsolate(), result,
8221 accessor->AddElementsToFixedArray(array, content, filter), FixedArray);
8222 8146
8223 #ifdef ENABLE_SLOW_DCHECKS 8147 #ifdef ENABLE_SLOW_DCHECKS
8224 if (FLAG_enable_slow_asserts) { 8148 if (FLAG_enable_slow_asserts) {
8225 DisallowHeapAllocation no_allocation; 8149 DisallowHeapAllocation no_allocation;
8226 for (int i = 0; i < result->length(); i++) { 8150 for (int i = 0; i < result->length(); i++) {
8227 Object* current = result->get(i); 8151 Object* current = result->get(i);
8228 DCHECK(current->IsNumber() || current->IsName()); 8152 DCHECK(current->IsNumber() || current->IsName());
8229 } 8153 }
8230 } 8154 }
8231 #endif 8155 #endif
(...skipping 4005 matching lines...) Expand 10 before | Expand all | Expand 10 after
12237 DCHECK(array->AllowsSetElementsLength()); 12161 DCHECK(array->AllowsSetElementsLength());
12238 if (!array->map()->is_observed()) { 12162 if (!array->map()->is_observed()) {
12239 return array->GetElementsAccessor()->SetLength(array, new_length_handle); 12163 return array->GetElementsAccessor()->SetLength(array, new_length_handle);
12240 } 12164 }
12241 12165
12242 Isolate* isolate = array->GetIsolate(); 12166 Isolate* isolate = array->GetIsolate();
12243 List<uint32_t> indices; 12167 List<uint32_t> indices;
12244 List<Handle<Object> > old_values; 12168 List<Handle<Object> > old_values;
12245 Handle<Object> old_length_handle(array->length(), isolate); 12169 Handle<Object> old_length_handle(array->length(), isolate);
12246 uint32_t old_length = 0; 12170 uint32_t old_length = 0;
12247 CHECK(old_length_handle->ToArrayIndex(&old_length)); 12171 CHECK(old_length_handle->ToArrayLength(&old_length));
12248 uint32_t new_length = 0; 12172 uint32_t new_length = 0;
12249 CHECK(new_length_handle->ToArrayIndex(&new_length)); 12173 CHECK(new_length_handle->ToArrayLength(&new_length));
12250 12174
12251 static const PropertyAttributes kNoAttrFilter = NONE; 12175 static const PropertyAttributes kNoAttrFilter = NONE;
12252 int num_elements = array->NumberOfOwnElements(kNoAttrFilter); 12176 int num_elements = array->NumberOfOwnElements(kNoAttrFilter);
12253 if (num_elements > 0) { 12177 if (num_elements > 0) {
12254 if (old_length == static_cast<uint32_t>(num_elements)) { 12178 if (old_length == static_cast<uint32_t>(num_elements)) {
12255 // Simple case for arrays without holes. 12179 // Simple case for arrays without holes.
12256 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { 12180 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) {
12257 if (!GetOldValue(isolate, array, i, &old_values, &indices)) break; 12181 if (!GetOldValue(isolate, array, i, &old_values, &indices)) break;
12258 } 12182 }
12259 } else { 12183 } else {
12260 // For sparse arrays, only iterate over existing elements. 12184 // For sparse arrays, only iterate over existing elements.
12261 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over 12185 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over
12262 // the to-be-removed indices twice. 12186 // the to-be-removed indices twice.
12263 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); 12187 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements);
12264 array->GetOwnElementKeys(*keys, kNoAttrFilter); 12188 array->GetOwnElementKeys(*keys, kNoAttrFilter);
12265 while (num_elements-- > 0) { 12189 while (num_elements-- > 0) {
12266 uint32_t index = NumberToUint32(keys->get(num_elements)); 12190 uint32_t index = NumberToUint32(keys->get(num_elements));
12267 if (index < new_length) break; 12191 if (index < new_length) break;
12268 if (!GetOldValue(isolate, array, index, &old_values, &indices)) break; 12192 if (!GetOldValue(isolate, array, index, &old_values, &indices)) break;
12269 } 12193 }
12270 } 12194 }
12271 } 12195 }
12272 12196
12273 Handle<Object> hresult; 12197 Handle<Object> hresult;
12274 ASSIGN_RETURN_ON_EXCEPTION( 12198 ASSIGN_RETURN_ON_EXCEPTION(
12275 isolate, hresult, 12199 isolate, hresult,
12276 array->GetElementsAccessor()->SetLength(array, new_length_handle), 12200 array->GetElementsAccessor()->SetLength(array, new_length_handle),
12277 Object); 12201 Object);
12278 12202
12279 CHECK(array->length()->ToArrayIndex(&new_length)); 12203 CHECK(array->length()->ToArrayLength(&new_length));
12280 if (old_length == new_length) return hresult; 12204 if (old_length == new_length) return hresult;
12281 12205
12282 RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object); 12206 RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object);
12283 12207
12284 for (int i = 0; i < indices.length(); ++i) { 12208 for (int i = 0; i < indices.length(); ++i) {
12285 // For deletions where the property was an accessor, old_values[i] 12209 // For deletions where the property was an accessor, old_values[i]
12286 // will be the hole, which instructs EnqueueChangeRecord to elide 12210 // will be the hole, which instructs EnqueueChangeRecord to elide
12287 // the "oldValue" property. 12211 // the "oldValue" property.
12288 RETURN_ON_EXCEPTION( 12212 RETURN_ON_EXCEPTION(
12289 isolate, 12213 isolate,
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
12758 args.Call(setter, index, v8::Utils::ToLocal(value)); 12682 args.Call(setter, index, v8::Utils::ToLocal(value));
12759 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 12683 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
12760 if (!result.IsEmpty()) return value; 12684 if (!result.IsEmpty()) return value;
12761 } 12685 }
12762 12686
12763 return SetElementWithoutInterceptor(object, index, value, attributes, 12687 return SetElementWithoutInterceptor(object, index, value, attributes,
12764 language_mode, check_prototype, set_mode); 12688 language_mode, check_prototype, set_mode);
12765 } 12689 }
12766 12690
12767 12691
12768 MaybeHandle<Object> JSObject::GetElementWithCallback(
12769 Handle<JSObject> object,
12770 Handle<Object> receiver,
12771 Handle<Object> structure,
12772 uint32_t index,
12773 Handle<Object> holder) {
12774 Isolate* isolate = object->GetIsolate();
12775 DCHECK(!structure->IsForeign());
12776 // api style callbacks.
12777 if (structure->IsExecutableAccessorInfo()) {
12778 Handle<ExecutableAccessorInfo> data =
12779 Handle<ExecutableAccessorInfo>::cast(structure);
12780 Object* fun_obj = data->getter();
12781 v8::AccessorNameGetterCallback call_fun =
12782 v8::ToCData<v8::AccessorNameGetterCallback>(fun_obj);
12783 if (call_fun == NULL) return isolate->factory()->undefined_value();
12784 Handle<JSObject> holder_handle = Handle<JSObject>::cast(holder);
12785 Handle<String> key = isolate->factory()->Uint32ToString(index);
12786 LOG(isolate, ApiNamedPropertyAccess("load", *holder_handle, *key));
12787 PropertyCallbackArguments
12788 args(isolate, data->data(), *receiver, *holder_handle);
12789 v8::Handle<v8::Value> result = args.Call(call_fun, v8::Utils::ToLocal(key));
12790 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
12791 if (result.IsEmpty()) return isolate->factory()->undefined_value();
12792 Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
12793 result_internal->VerifyApiCallResultType();
12794 // Rebox handle before return.
12795 return handle(*result_internal, isolate);
12796 }
12797
12798 // __defineGetter__ callback
12799 if (structure->IsAccessorPair()) {
12800 Handle<Object> getter(Handle<AccessorPair>::cast(structure)->getter(),
12801 isolate);
12802 if (getter->IsSpecFunction()) {
12803 // TODO(rossberg): nicer would be to cast to some JSCallable here...
12804 return GetPropertyWithDefinedGetter(
12805 receiver, Handle<JSReceiver>::cast(getter));
12806 }
12807 // Getter is not a function.
12808 return isolate->factory()->undefined_value();
12809 }
12810
12811 UNREACHABLE();
12812 return MaybeHandle<Object>();
12813 }
12814
12815
12816 MaybeHandle<Object> JSObject::SetElementWithCallback( 12692 MaybeHandle<Object> JSObject::SetElementWithCallback(
12817 Handle<Object> object, Handle<Object> structure, uint32_t index, 12693 Handle<Object> object, Handle<Object> structure, uint32_t index,
12818 Handle<Object> value, Handle<JSObject> holder, LanguageMode language_mode) { 12694 Handle<Object> value, Handle<JSObject> holder, LanguageMode language_mode) {
12819 Isolate* isolate = holder->GetIsolate(); 12695 Isolate* isolate = holder->GetIsolate();
12820 12696
12821 // We should never get here to initialize a const with the hole 12697 // We should never get here to initialize a const with the hole
12822 // value since a const declaration would conflict with the setter. 12698 // value since a const declaration would conflict with the setter.
12823 DCHECK(!value->IsTheHole()); 12699 DCHECK(!value->IsTheHole());
12824 DCHECK(!structure->IsForeign()); 12700 DCHECK(!structure->IsForeign());
12825 if (structure->IsExecutableAccessorInfo()) { 12701 if (structure->IsExecutableAccessorInfo()) {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
12920 object, index, value, &found, language_mode); 12796 object, index, value, &found, language_mode);
12921 if (found) return result; 12797 if (found) return result;
12922 } 12798 }
12923 12799
12924 uint32_t new_capacity = capacity; 12800 uint32_t new_capacity = capacity;
12925 // Check if the length property of this object needs to be updated. 12801 // Check if the length property of this object needs to be updated.
12926 uint32_t array_length = 0; 12802 uint32_t array_length = 0;
12927 bool must_update_array_length = false; 12803 bool must_update_array_length = false;
12928 bool introduces_holes = true; 12804 bool introduces_holes = true;
12929 if (object->IsJSArray()) { 12805 if (object->IsJSArray()) {
12930 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length)); 12806 CHECK(
12807 Handle<JSArray>::cast(object)->length()->ToArrayLength(&array_length));
12931 introduces_holes = index > array_length; 12808 introduces_holes = index > array_length;
12932 if (index >= array_length) { 12809 if (index >= array_length) {
12933 must_update_array_length = true; 12810 must_update_array_length = true;
12934 array_length = index + 1; 12811 array_length = index + 1;
12935 } 12812 }
12936 } else { 12813 } else {
12937 introduces_holes = index >= capacity; 12814 introduces_holes = index >= capacity;
12938 } 12815 }
12939 12816
12940 // If the array is growing, and it's not growth by a single element at the 12817 // If the array is growing, and it's not growth by a single element at the
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
13115 // Update the array length if this JSObject is an array. 12992 // Update the array length if this JSObject is an array.
13116 if (object->IsJSArray()) { 12993 if (object->IsJSArray()) {
13117 JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray>::cast(object), index, 12994 JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray>::cast(object), index,
13118 value); 12995 value);
13119 } 12996 }
13120 12997
13121 // Attempt to put this object back in fast case. 12998 // Attempt to put this object back in fast case.
13122 if (object->ShouldConvertToFastElements()) { 12999 if (object->ShouldConvertToFastElements()) {
13123 uint32_t new_length = 0; 13000 uint32_t new_length = 0;
13124 if (object->IsJSArray()) { 13001 if (object->IsJSArray()) {
13125 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&new_length)); 13002 CHECK(
13003 Handle<JSArray>::cast(object)->length()->ToArrayLength(&new_length));
13126 } else { 13004 } else {
13127 new_length = dictionary->max_number_key() + 1; 13005 new_length = dictionary->max_number_key() + 1;
13128 } 13006 }
13129 bool has_smi_only_elements = false; 13007 bool has_smi_only_elements = false;
13130 bool should_convert_to_fast_double_elements = 13008 bool should_convert_to_fast_double_elements =
13131 object->ShouldConvertToFastDoubleElements(&has_smi_only_elements); 13009 object->ShouldConvertToFastDoubleElements(&has_smi_only_elements);
13132 SetFastElementsCapacitySmiMode smi_mode = 13010 SetFastElementsCapacitySmiMode smi_mode =
13133 has_smi_only_elements ? kForceSmiElements : kAllowSmiElements; 13011 has_smi_only_elements ? kForceSmiElements : kAllowSmiElements;
13134 13012
13135 if (should_convert_to_fast_double_elements) { 13013 if (should_convert_to_fast_double_elements) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
13170 object, index, value, &found, language_mode); 13048 object, index, value, &found, language_mode);
13171 if (found) return result; 13049 if (found) return result;
13172 } 13050 }
13173 13051
13174 // If the value object is not a heap number, switch to fast elements and try 13052 // If the value object is not a heap number, switch to fast elements and try
13175 // again. 13053 // again.
13176 bool value_is_smi = value->IsSmi(); 13054 bool value_is_smi = value->IsSmi();
13177 bool introduces_holes = true; 13055 bool introduces_holes = true;
13178 uint32_t length = elms_length; 13056 uint32_t length = elms_length;
13179 if (object->IsJSArray()) { 13057 if (object->IsJSArray()) {
13180 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&length)); 13058 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayLength(&length));
13181 introduces_holes = index > length; 13059 introduces_holes = index > length;
13182 } else { 13060 } else {
13183 introduces_holes = index >= elms_length; 13061 introduces_holes = index >= elms_length;
13184 } 13062 }
13185 13063
13186 if (!value->IsNumber()) { 13064 if (!value->IsNumber()) {
13187 SetFastElementsCapacityAndLength(object, elms_length, length, 13065 SetFastElementsCapacityAndLength(object, elms_length, length,
13188 kDontAllowSmiElements); 13066 kDontAllowSmiElements);
13189 Handle<Object> result; 13067 Handle<Object> result;
13190 ASSIGN_RETURN_ON_EXCEPTION( 13068 ASSIGN_RETURN_ON_EXCEPTION(
(...skipping 16 matching lines...) Expand all
13207 TransitionElementsKind(object, transitioned_kind); 13085 TransitionElementsKind(object, transitioned_kind);
13208 } 13086 }
13209 13087
13210 // Check whether there is extra space in the fixed array. 13088 // Check whether there is extra space in the fixed array.
13211 if (index < elms_length) { 13089 if (index < elms_length) {
13212 Handle<FixedDoubleArray> elms(FixedDoubleArray::cast(object->elements())); 13090 Handle<FixedDoubleArray> elms(FixedDoubleArray::cast(object->elements()));
13213 elms->set(index, double_value); 13091 elms->set(index, double_value);
13214 if (object->IsJSArray()) { 13092 if (object->IsJSArray()) {
13215 // Update the length of the array if needed. 13093 // Update the length of the array if needed.
13216 uint32_t array_length = 0; 13094 uint32_t array_length = 0;
13217 CHECK( 13095 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayLength(
13218 Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length)); 13096 &array_length));
13219 if (index >= array_length) { 13097 if (index >= array_length) {
13220 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(index + 1)); 13098 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(index + 1));
13221 } 13099 }
13222 } 13100 }
13223 return value; 13101 return value;
13224 } 13102 }
13225 13103
13226 // Allow gap in fast case. 13104 // Allow gap in fast case.
13227 if ((index - elms_length) < kMaxGap) { 13105 if ((index - elms_length) < kMaxGap) {
13228 // Try allocating extra space. 13106 // Try allocating extra space.
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
13369 PropertyAttributes new_attributes = maybe.FromJust(); 13247 PropertyAttributes new_attributes = maybe.FromJust();
13370 13248
13371 if (old_attributes == ABSENT) { 13249 if (old_attributes == ABSENT) {
13372 if (object->IsJSArray() && 13250 if (object->IsJSArray() &&
13373 !old_length_handle->SameValue( 13251 !old_length_handle->SameValue(
13374 Handle<JSArray>::cast(object)->length())) { 13252 Handle<JSArray>::cast(object)->length())) {
13375 new_length_handle = handle(Handle<JSArray>::cast(object)->length(), 13253 new_length_handle = handle(Handle<JSArray>::cast(object)->length(),
13376 isolate); 13254 isolate);
13377 uint32_t old_length = 0; 13255 uint32_t old_length = 0;
13378 uint32_t new_length = 0; 13256 uint32_t new_length = 0;
13379 CHECK(old_length_handle->ToArrayIndex(&old_length)); 13257 CHECK(old_length_handle->ToArrayLength(&old_length));
13380 CHECK(new_length_handle->ToArrayIndex(&new_length)); 13258 CHECK(new_length_handle->ToArrayLength(&new_length));
13381 13259
13382 RETURN_ON_EXCEPTION( 13260 RETURN_ON_EXCEPTION(
13383 isolate, BeginPerformSplice(Handle<JSArray>::cast(object)), Object); 13261 isolate, BeginPerformSplice(Handle<JSArray>::cast(object)), Object);
13384 RETURN_ON_EXCEPTION( 13262 RETURN_ON_EXCEPTION(
13385 isolate, EnqueueChangeRecord(object, "add", name, old_value), Object); 13263 isolate, EnqueueChangeRecord(object, "add", name, old_value), Object);
13386 RETURN_ON_EXCEPTION( 13264 RETURN_ON_EXCEPTION(
13387 isolate, EnqueueChangeRecord(object, "update", 13265 isolate, EnqueueChangeRecord(object, "update",
13388 isolate->factory()->length_string(), 13266 isolate->factory()->length_string(),
13389 old_length_handle), 13267 old_length_handle),
13390 Object); 13268 Object);
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
13558 handle(JSArray::cast(site->transition_info())); 13436 handle(JSArray::cast(site->transition_info()));
13559 ElementsKind kind = transition_info->GetElementsKind(); 13437 ElementsKind kind = transition_info->GetElementsKind();
13560 // if kind is holey ensure that to_kind is as well. 13438 // if kind is holey ensure that to_kind is as well.
13561 if (IsHoleyElementsKind(kind)) { 13439 if (IsHoleyElementsKind(kind)) {
13562 to_kind = GetHoleyElementsKind(to_kind); 13440 to_kind = GetHoleyElementsKind(to_kind);
13563 } 13441 }
13564 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { 13442 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
13565 // If the array is huge, it's not likely to be defined in a local 13443 // If the array is huge, it's not likely to be defined in a local
13566 // function, so we shouldn't make new instances of it very often. 13444 // function, so we shouldn't make new instances of it very often.
13567 uint32_t length = 0; 13445 uint32_t length = 0;
13568 CHECK(transition_info->length()->ToArrayIndex(&length)); 13446 CHECK(transition_info->length()->ToArrayLength(&length));
13569 if (length <= kMaximumArrayBytesToPretransition) { 13447 if (length <= kMaximumArrayBytesToPretransition) {
13570 if (FLAG_trace_track_allocation_sites) { 13448 if (FLAG_trace_track_allocation_sites) {
13571 bool is_nested = site->IsNestedSite(); 13449 bool is_nested = site->IsNestedSite();
13572 PrintF( 13450 PrintF(
13573 "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n", 13451 "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n",
13574 reinterpret_cast<void*>(*site), 13452 reinterpret_cast<void*>(*site),
13575 is_nested ? "(nested)" : "", 13453 is_nested ? "(nested)" : "",
13576 ElementsKindToString(kind), 13454 ElementsKindToString(kind),
13577 ElementsKindToString(to_kind)); 13455 ElementsKindToString(to_kind));
13578 } 13456 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
13672 uint32_t capacity = static_cast<uint32_t>(elms->length()); 13550 uint32_t capacity = static_cast<uint32_t>(elms->length());
13673 uint32_t length = capacity; 13551 uint32_t length = capacity;
13674 13552
13675 if (object->IsJSArray()) { 13553 if (object->IsJSArray()) {
13676 Object* raw_length = Handle<JSArray>::cast(object)->length(); 13554 Object* raw_length = Handle<JSArray>::cast(object)->length();
13677 if (raw_length->IsUndefined()) { 13555 if (raw_length->IsUndefined()) {
13678 // If length is undefined, then JSArray is being initialized and has no 13556 // If length is undefined, then JSArray is being initialized and has no
13679 // elements, assume a length of zero. 13557 // elements, assume a length of zero.
13680 length = 0; 13558 length = 0;
13681 } else { 13559 } else {
13682 CHECK(raw_length->ToArrayIndex(&length)); 13560 CHECK(raw_length->ToArrayLength(&length));
13683 } 13561 }
13684 } 13562 }
13685 13563
13686 if (IsFastSmiElementsKind(from_kind) && 13564 if (IsFastSmiElementsKind(from_kind) &&
13687 IsFastDoubleElementsKind(to_kind)) { 13565 IsFastDoubleElementsKind(to_kind)) {
13688 SetFastDoubleElementsCapacityAndLength(object, capacity, length); 13566 SetFastDoubleElementsCapacityAndLength(object, capacity, length);
13689 JSObject::ValidateElements(object); 13567 JSObject::ValidateElements(object);
13690 return; 13568 return;
13691 } 13569 }
13692 13570
(...skipping 22 matching lines...) Expand all
13715 // Transitions from HOLEY -> PACKED are not allowed. 13593 // Transitions from HOLEY -> PACKED are not allowed.
13716 return !IsFastHoleyElementsKind(from_kind) || 13594 return !IsFastHoleyElementsKind(from_kind) ||
13717 IsFastHoleyElementsKind(to_kind); 13595 IsFastHoleyElementsKind(to_kind);
13718 } 13596 }
13719 13597
13720 13598
13721 void JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray> array, 13599 void JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray> array,
13722 uint32_t index, 13600 uint32_t index,
13723 Handle<Object> value) { 13601 Handle<Object> value) {
13724 uint32_t old_len = 0; 13602 uint32_t old_len = 0;
13725 CHECK(array->length()->ToArrayIndex(&old_len)); 13603 CHECK(array->length()->ToArrayLength(&old_len));
13726 // Check to see if we need to update the length. For now, we make 13604 // Check to see if we need to update the length. For now, we make
13727 // sure that the length stays within 32-bits (unsigned). 13605 // sure that the length stays within 32-bits (unsigned).
13728 if (index >= old_len && index != 0xffffffff) { 13606 if (index >= old_len && index != 0xffffffff) {
13729 Handle<Object> len = array->GetIsolate()->factory()->NewNumber( 13607 Handle<Object> len = array->GetIsolate()->factory()->NewNumber(
13730 static_cast<double>(index) + 1); 13608 static_cast<double>(index) + 1);
13731 array->set_length(*len); 13609 array->set_length(*len);
13732 } 13610 }
13733 } 13611 }
13734 13612
13735 13613
13736 bool JSArray::HasReadOnlyLength(Handle<JSArray> array) { 13614 bool JSArray::HasReadOnlyLength(Handle<JSArray> array) {
13737 LookupIterator it(array, array->GetIsolate()->factory()->length_string(), 13615 LookupIterator it(array, array->GetIsolate()->factory()->length_string(),
13738 LookupIterator::OWN_SKIP_INTERCEPTOR); 13616 LookupIterator::OWN_SKIP_INTERCEPTOR);
13739 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state()); 13617 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
13740 CHECK(it.IsFound()); 13618 CHECK(it.IsFound());
13741 CHECK_EQ(LookupIterator::ACCESSOR, it.state()); 13619 CHECK_EQ(LookupIterator::ACCESSOR, it.state());
13742 return it.IsReadOnly(); 13620 return it.IsReadOnly();
13743 } 13621 }
13744 13622
13745 13623
13746 bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array, 13624 bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
13747 uint32_t index) { 13625 uint32_t index) {
13748 uint32_t length = 0; 13626 uint32_t length = 0;
13749 CHECK(array->length()->ToArrayIndex(&length)); 13627 CHECK(array->length()->ToArrayLength(&length));
13750 if (length <= index) return HasReadOnlyLength(array); 13628 if (length <= index) return HasReadOnlyLength(array);
13751 return false; 13629 return false;
13752 } 13630 }
13753 13631
13754 13632
13755 MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) { 13633 MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) {
13756 Isolate* isolate = array->GetIsolate(); 13634 Isolate* isolate = array->GetIsolate();
13757 Handle<Name> length = isolate->factory()->length_string(); 13635 Handle<Name> length = isolate->factory()->length_string();
13758 THROW_NEW_ERROR( 13636 THROW_NEW_ERROR(
13759 isolate, 13637 isolate,
13760 NewTypeError(MessageTemplate::kStrictReadOnlyProperty, length, array), 13638 NewTypeError(MessageTemplate::kStrictReadOnlyProperty, length, array),
13761 Object); 13639 Object);
13762 } 13640 }
13763 13641
13764 13642
13765 MaybeHandle<Object> JSObject::GetElementWithInterceptor(Handle<JSObject> object,
13766 Handle<Object> receiver,
13767 uint32_t index,
13768 bool check_prototype) {
13769 Isolate* isolate = object->GetIsolate();
13770
13771 // Make sure that the top context does not change when doing
13772 // callbacks or interceptor calls.
13773 AssertNoContextChange ncc(isolate);
13774
13775 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor(), isolate);
13776 if (!interceptor->getter()->IsUndefined()) {
13777 v8::IndexedPropertyGetterCallback getter =
13778 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
13779 LOG(isolate,
13780 ApiIndexedPropertyAccess("interceptor-indexed-get", *object, index));
13781 PropertyCallbackArguments
13782 args(isolate, interceptor->data(), *receiver, *object);
13783 v8::Handle<v8::Value> result = args.Call(getter, index);
13784 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
13785 if (!result.IsEmpty()) {
13786 Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
13787 result_internal->VerifyApiCallResultType();
13788 // Rebox handle before return.
13789 return handle(*result_internal, isolate);
13790 }
13791 }
13792
13793 if (!check_prototype) return MaybeHandle<Object>();
13794
13795 ElementsAccessor* handler = object->GetElementsAccessor();
13796 Handle<Object> result;
13797 ASSIGN_RETURN_ON_EXCEPTION(
13798 isolate, result, handler->Get(receiver, object, index),
13799 Object);
13800 if (!result->IsTheHole()) return result;
13801
13802 PrototypeIterator iter(isolate, object);
13803 if (iter.IsAtEnd()) return isolate->factory()->undefined_value();
13804 return Object::GetElementWithReceiver(
13805 isolate, PrototypeIterator::GetCurrent(iter), receiver, index);
13806 }
13807
13808
13809 bool JSObject::HasDenseElements() { 13643 bool JSObject::HasDenseElements() {
13810 int capacity = 0; 13644 int capacity = 0;
13811 int used = 0; 13645 int used = 0;
13812 GetElementsCapacityAndUsage(&capacity, &used); 13646 GetElementsCapacityAndUsage(&capacity, &used);
13813 return (capacity == 0) || (used > (capacity / 2)); 13647 return (capacity == 0) || (used > (capacity / 2));
13814 } 13648 }
13815 13649
13816 13650
13817 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { 13651 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) {
13818 *capacity = 0; 13652 *capacity = 0;
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
13942 dictionary = SeededNumberDictionary::cast(elements); 13776 dictionary = SeededNumberDictionary::cast(elements);
13943 } 13777 }
13944 // If an element has been added at a very high index in the elements 13778 // If an element has been added at a very high index in the elements
13945 // dictionary, we cannot go back to fast case. 13779 // dictionary, we cannot go back to fast case.
13946 if (dictionary->requires_slow_elements()) return false; 13780 if (dictionary->requires_slow_elements()) return false;
13947 // If the dictionary backing storage takes up roughly half as much 13781 // If the dictionary backing storage takes up roughly half as much
13948 // space (in machine words) as a fast-case backing storage would, 13782 // space (in machine words) as a fast-case backing storage would,
13949 // the object should have fast elements. 13783 // the object should have fast elements.
13950 uint32_t array_size = 0; 13784 uint32_t array_size = 0;
13951 if (IsJSArray()) { 13785 if (IsJSArray()) {
13952 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_size)); 13786 CHECK(JSArray::cast(this)->length()->ToArrayLength(&array_size));
13953 } else { 13787 } else {
13954 array_size = dictionary->max_number_key(); 13788 array_size = dictionary->max_number_key();
13955 } 13789 }
13956 uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) * 13790 uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) *
13957 SeededNumberDictionary::kEntrySize; 13791 SeededNumberDictionary::kEntrySize;
13958 return 2 * dictionary_size >= array_size; 13792 return 2 * dictionary_size >= array_size;
13959 } 13793 }
13960 13794
13961 13795
13962 bool JSObject::ShouldConvertToFastDoubleElements( 13796 bool JSObject::ShouldConvertToFastDoubleElements(
(...skipping 3365 matching lines...) Expand 10 before | Expand all | Expand 10 after
17328 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, 17162 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell,
17329 Handle<Object> new_value) { 17163 Handle<Object> new_value) {
17330 if (cell->value() != *new_value) { 17164 if (cell->value() != *new_value) {
17331 cell->set_value(*new_value); 17165 cell->set_value(*new_value);
17332 Isolate* isolate = cell->GetIsolate(); 17166 Isolate* isolate = cell->GetIsolate();
17333 cell->dependent_code()->DeoptimizeDependentCodeGroup( 17167 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17334 isolate, DependentCode::kPropertyCellChangedGroup); 17168 isolate, DependentCode::kPropertyCellChangedGroup);
17335 } 17169 }
17336 } 17170 }
17337 } } // namespace v8::internal 17171 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698