OLD | NEW |
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 "src/elements.h" | 5 #include "src/elements.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
9 #include "src/factory.h" | 9 #include "src/factory.h" |
10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 DCHECK(IsFastSmiOrObjectElementsKind(to_kind)); | 178 DCHECK(IsFastSmiOrObjectElementsKind(to_kind)); |
179 if (copy_size == 0) return; | 179 if (copy_size == 0) return; |
180 FixedArray* to = FixedArray::cast(to_base); | 180 FixedArray* to = FixedArray::cast(to_base); |
181 uint32_t to_length = to->length(); | 181 uint32_t to_length = to->length(); |
182 if (to_start + copy_size > to_length) { | 182 if (to_start + copy_size > to_length) { |
183 copy_size = to_length - to_start; | 183 copy_size = to_length - to_start; |
184 } | 184 } |
185 WriteBarrierMode write_barrier_mode = IsFastObjectElementsKind(to_kind) | 185 WriteBarrierMode write_barrier_mode = IsFastObjectElementsKind(to_kind) |
186 ? UPDATE_WRITE_BARRIER | 186 ? UPDATE_WRITE_BARRIER |
187 : SKIP_WRITE_BARRIER; | 187 : SKIP_WRITE_BARRIER; |
| 188 Isolate* isolate = from->GetIsolate(); |
188 for (int i = 0; i < copy_size; i++) { | 189 for (int i = 0; i < copy_size; i++) { |
189 int entry = from->FindEntry(i + from_start); | 190 int entry = from->FindEntry(i + from_start); |
190 if (entry != SeededNumberDictionary::kNotFound) { | 191 if (entry != SeededNumberDictionary::kNotFound) { |
191 Object* value = from->ValueAt(entry); | 192 Object* value = from->ValueAt(entry); |
192 DCHECK(!value->IsTheHole(from->GetIsolate())); | 193 DCHECK(!value->IsTheHole(isolate)); |
193 to->set(i + to_start, value, write_barrier_mode); | 194 to->set(i + to_start, value, write_barrier_mode); |
194 } else { | 195 } else { |
195 to->set_the_hole(i + to_start); | 196 to->set_the_hole(isolate, i + to_start); |
196 } | 197 } |
197 } | 198 } |
198 } | 199 } |
199 | 200 |
200 | 201 |
201 // NOTE: this method violates the handlified function signature convention: | 202 // NOTE: this method violates the handlified function signature convention: |
202 // raw pointer parameters in the function that allocates. | 203 // raw pointer parameters in the function that allocates. |
203 // See ElementsAccessorBase::CopyElements() for details. | 204 // See ElementsAccessorBase::CopyElements() for details. |
204 static void CopyDoubleToObjectElements(FixedArrayBase* from_base, | 205 static void CopyDoubleToObjectElements(FixedArrayBase* from_base, |
205 uint32_t from_start, | 206 uint32_t from_start, |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 JSObject::EnsureWritableFastElements(array); | 755 JSObject::EnsureWritableFastElements(array); |
755 if (array->elements() != *backing_store) { | 756 if (array->elements() != *backing_store) { |
756 backing_store = handle(array->elements(), isolate); | 757 backing_store = handle(array->elements(), isolate); |
757 } | 758 } |
758 } | 759 } |
759 if (2 * length <= capacity) { | 760 if (2 * length <= capacity) { |
760 // If more than half the elements won't be used, trim the array. | 761 // If more than half the elements won't be used, trim the array. |
761 isolate->heap()->RightTrimFixedArray(*backing_store, capacity - length); | 762 isolate->heap()->RightTrimFixedArray(*backing_store, capacity - length); |
762 } else { | 763 } else { |
763 // Otherwise, fill the unused tail with holes. | 764 // Otherwise, fill the unused tail with holes. |
764 for (uint32_t i = length; i < old_length; i++) { | 765 BackingStore::cast(*backing_store)->FillWithHoles(length, old_length); |
765 BackingStore::cast(*backing_store)->set_the_hole(i); | |
766 } | |
767 } | 766 } |
768 } else { | 767 } else { |
769 // Check whether the backing store should be expanded. | 768 // Check whether the backing store should be expanded. |
770 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); | 769 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); |
771 Subclass::GrowCapacityAndConvertImpl(array, capacity); | 770 Subclass::GrowCapacityAndConvertImpl(array, capacity); |
772 } | 771 } |
773 | 772 |
774 array->set_length(Smi::FromInt(length)); | 773 array->set_length(Smi::FromInt(length)); |
775 JSObject::ValidateElements(array); | 774 JSObject::ValidateElements(array); |
776 } | 775 } |
(...skipping 1030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1807 obj->HasFastArgumentsElements() || | 1806 obj->HasFastArgumentsElements() || |
1808 obj->HasFastStringWrapperElements()); | 1807 obj->HasFastStringWrapperElements()); |
1809 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store); | 1808 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store); |
1810 if (!obj->IsJSArray() && | 1809 if (!obj->IsJSArray() && |
1811 entry == static_cast<uint32_t>(store->length()) - 1) { | 1810 entry == static_cast<uint32_t>(store->length()) - 1) { |
1812 DeleteAtEnd(obj, backing_store, entry); | 1811 DeleteAtEnd(obj, backing_store, entry); |
1813 return; | 1812 return; |
1814 } | 1813 } |
1815 | 1814 |
1816 Isolate* isolate = obj->GetIsolate(); | 1815 Isolate* isolate = obj->GetIsolate(); |
1817 backing_store->set_the_hole(entry); | 1816 backing_store->set_the_hole(isolate, entry); |
1818 | 1817 |
1819 // TODO(verwaest): Move this out of elements.cc. | 1818 // TODO(verwaest): Move this out of elements.cc. |
1820 // If an old space backing store is larger than a certain size and | 1819 // If an old space backing store is larger than a certain size and |
1821 // has too few used values, normalize it. | 1820 // has too few used values, normalize it. |
1822 // To avoid doing the check on every delete we require at least | 1821 // To avoid doing the check on every delete we require at least |
1823 // one adjacent hole to the value being deleted. | 1822 // one adjacent hole to the value being deleted. |
1824 const int kMinLengthForSparsenessCheck = 64; | 1823 const int kMinLengthForSparsenessCheck = 64; |
1825 if (backing_store->length() < kMinLengthForSparsenessCheck) return; | 1824 if (backing_store->length() < kMinLengthForSparsenessCheck) return; |
1826 if (backing_store->GetHeap()->InNewSpace(*backing_store)) return; | 1825 if (backing_store->GetHeap()->InNewSpace(*backing_store)) return; |
1827 uint32_t length = 0; | 1826 uint32_t length = 0; |
(...skipping 1446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3274 Isolate* isolate = store->GetIsolate(); | 3273 Isolate* isolate = store->GetIsolate(); |
3275 if (entry < length) { | 3274 if (entry < length) { |
3276 Object* probe = parameter_map->get(entry + 2); | 3275 Object* probe = parameter_map->get(entry + 2); |
3277 DCHECK(!probe->IsTheHole(isolate)); | 3276 DCHECK(!probe->IsTheHole(isolate)); |
3278 Context* context = Context::cast(parameter_map->get(0)); | 3277 Context* context = Context::cast(parameter_map->get(0)); |
3279 int context_entry = Smi::cast(probe)->value(); | 3278 int context_entry = Smi::cast(probe)->value(); |
3280 DCHECK(!context->get(context_entry)->IsTheHole(isolate)); | 3279 DCHECK(!context->get(context_entry)->IsTheHole(isolate)); |
3281 context->set(context_entry, *value); | 3280 context->set(context_entry, *value); |
3282 | 3281 |
3283 // Redefining attributes of an aliased element destroys fast aliasing. | 3282 // Redefining attributes of an aliased element destroys fast aliasing. |
3284 parameter_map->set_the_hole(entry + 2); | 3283 parameter_map->set_the_hole(isolate, entry + 2); |
3285 // For elements that are still writable we re-establish slow aliasing. | 3284 // For elements that are still writable we re-establish slow aliasing. |
3286 if ((attributes & READ_ONLY) == 0) { | 3285 if ((attributes & READ_ONLY) == 0) { |
3287 value = isolate->factory()->NewAliasedArgumentsEntry(context_entry); | 3286 value = isolate->factory()->NewAliasedArgumentsEntry(context_entry); |
3288 } | 3287 } |
3289 | 3288 |
3290 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); | 3289 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); |
3291 Handle<SeededNumberDictionary> arguments( | 3290 Handle<SeededNumberDictionary> arguments( |
3292 SeededNumberDictionary::cast(parameter_map->get(1)), isolate); | 3291 SeededNumberDictionary::cast(parameter_map->get(1)), isolate); |
3293 arguments = SeededNumberDictionary::AddNumberEntry( | 3292 arguments = SeededNumberDictionary::AddNumberEntry( |
3294 arguments, entry, value, details, object->map()->is_prototype_map()); | 3293 arguments, entry, value, details, object->map()->is_prototype_map()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3333 DisallowHeapAllocation no_gc; | 3332 DisallowHeapAllocation no_gc; |
3334 FixedArray* elements = FixedArray::cast(result_array->elements()); | 3333 FixedArray* elements = FixedArray::cast(result_array->elements()); |
3335 FixedArray* parameters = FixedArray::cast(receiver->elements()); | 3334 FixedArray* parameters = FixedArray::cast(receiver->elements()); |
3336 uint32_t insertion_index = 0; | 3335 uint32_t insertion_index = 0; |
3337 for (uint32_t i = start; i < end; i++) { | 3336 for (uint32_t i = start; i < end; i++) { |
3338 uint32_t entry = GetEntryForIndexImpl(isolate, *receiver, parameters, i, | 3337 uint32_t entry = GetEntryForIndexImpl(isolate, *receiver, parameters, i, |
3339 ALL_PROPERTIES); | 3338 ALL_PROPERTIES); |
3340 if (entry != kMaxUInt32 && HasEntryImpl(isolate, parameters, entry)) { | 3339 if (entry != kMaxUInt32 && HasEntryImpl(isolate, parameters, entry)) { |
3341 elements->set(insertion_index, *GetImpl(parameters, entry)); | 3340 elements->set(insertion_index, *GetImpl(parameters, entry)); |
3342 } else { | 3341 } else { |
3343 elements->set_the_hole(insertion_index); | 3342 elements->set_the_hole(isolate, insertion_index); |
3344 } | 3343 } |
3345 insertion_index++; | 3344 insertion_index++; |
3346 } | 3345 } |
3347 return result_array; | 3346 return result_array; |
3348 } | 3347 } |
3349 | 3348 |
3350 static Handle<SeededNumberDictionary> NormalizeImpl( | 3349 static Handle<SeededNumberDictionary> NormalizeImpl( |
3351 Handle<JSObject> object, Handle<FixedArrayBase> elements) { | 3350 Handle<JSObject> object, Handle<FixedArrayBase> elements) { |
3352 Handle<FixedArray> arguments = | 3351 Handle<FixedArray> arguments = |
3353 GetArguments(elements->GetIsolate(), *elements); | 3352 GetArguments(elements->GetIsolate(), *elements); |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3824 insertion_index += len; | 3823 insertion_index += len; |
3825 } | 3824 } |
3826 | 3825 |
3827 DCHECK_EQ(insertion_index, result_len); | 3826 DCHECK_EQ(insertion_index, result_len); |
3828 return result_array; | 3827 return result_array; |
3829 } | 3828 } |
3830 | 3829 |
3831 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3830 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
3832 } // namespace internal | 3831 } // namespace internal |
3833 } // namespace v8 | 3832 } // namespace v8 |
OLD | NEW |