| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index bac37a4c42a99f0a18e025999c4e7f3b362b7048..1ae7d549cab0740f740c105560f92e199d68d067 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -3140,48 +3140,6 @@ MaybeObject* JSObject::DeletePropertyWithInterceptor(String* name) {
|
| }
|
|
|
|
|
| -MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index,
|
| - DeleteMode mode) {
|
| - ASSERT(!HasExternalArrayElements());
|
| - switch (GetElementsKind()) {
|
| - case FAST_ELEMENTS: {
|
| - Object* obj;
|
| - { MaybeObject* maybe_obj = EnsureWritableFastElements();
|
| - if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| - }
|
| - uint32_t length = IsJSArray() ?
|
| - static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
|
| - static_cast<uint32_t>(FixedArray::cast(elements())->length());
|
| - if (index < length) {
|
| - FixedArray::cast(elements())->set_the_hole(index);
|
| - }
|
| - break;
|
| - }
|
| - case DICTIONARY_ELEMENTS: {
|
| - NumberDictionary* dictionary = element_dictionary();
|
| - int entry = dictionary->FindEntry(index);
|
| - if (entry != NumberDictionary::kNotFound) {
|
| - Object* deleted = dictionary->DeleteProperty(entry, mode);
|
| - if (deleted == GetHeap()->true_value()) {
|
| - MaybeObject* maybe_elements = dictionary->Shrink(index);
|
| - FixedArray* new_elements = NULL;
|
| - if (!maybe_elements->To(&new_elements)) {
|
| - return maybe_elements;
|
| - }
|
| - set_elements(new_elements);
|
| - }
|
| - return deleted;
|
| - }
|
| - break;
|
| - }
|
| - default:
|
| - UNREACHABLE();
|
| - break;
|
| - }
|
| - return GetHeap()->true_value();
|
| -}
|
| -
|
| -
|
| MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) {
|
| Isolate* isolate = GetIsolate();
|
| Heap* heap = isolate->heap();
|
| @@ -3209,100 +3167,14 @@ MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) {
|
| ASSERT(result->IsBoolean());
|
| return *v8::Utils::OpenHandle(*result);
|
| }
|
| - MaybeObject* raw_result =
|
| - this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION);
|
| + MaybeObject* raw_result = GetElementsAccessor()->Delete(*this_handle,
|
| + index,
|
| + NORMAL_DELETION);
|
| RETURN_IF_SCHEDULED_EXCEPTION(isolate);
|
| return raw_result;
|
| }
|
|
|
|
|
| -MaybeObject* JSObject::DeleteFastElement(uint32_t index) {
|
| - ASSERT(HasFastElements() || HasFastArgumentsElements());
|
| - Heap* heap = GetHeap();
|
| - FixedArray* backing_store = FixedArray::cast(elements());
|
| - if (backing_store->map() == heap->non_strict_arguments_elements_map()) {
|
| - backing_store = FixedArray::cast(backing_store->get(1));
|
| - } else {
|
| - Object* writable;
|
| - MaybeObject* maybe = EnsureWritableFastElements();
|
| - if (!maybe->ToObject(&writable)) return maybe;
|
| - backing_store = FixedArray::cast(writable);
|
| - }
|
| - uint32_t length = static_cast<uint32_t>(
|
| - IsJSArray()
|
| - ? Smi::cast(JSArray::cast(this)->length())->value()
|
| - : backing_store->length());
|
| - if (index < length) {
|
| - backing_store->set_the_hole(index);
|
| - // If an old space backing store is larger than a certain size and
|
| - // has too few used values, normalize it.
|
| - // To avoid doing the check on every delete we require at least
|
| - // one adjacent hole to the value being deleted.
|
| - Object* hole = heap->the_hole_value();
|
| - const int kMinLengthForSparsenessCheck = 64;
|
| - if (backing_store->length() >= kMinLengthForSparsenessCheck &&
|
| - !heap->InNewSpace(backing_store) &&
|
| - ((index > 0 && backing_store->get(index - 1) == hole) ||
|
| - (index + 1 < length && backing_store->get(index + 1) == hole))) {
|
| - int num_used = 0;
|
| - for (int i = 0; i < backing_store->length(); ++i) {
|
| - if (backing_store->get(i) != hole) ++num_used;
|
| - // Bail out early if more than 1/4 is used.
|
| - if (4 * num_used > backing_store->length()) break;
|
| - }
|
| - if (4 * num_used <= backing_store->length()) {
|
| - MaybeObject* result = NormalizeElements();
|
| - if (result->IsFailure()) return result;
|
| - }
|
| - }
|
| - }
|
| - return heap->true_value();
|
| -}
|
| -
|
| -
|
| -MaybeObject* JSObject::DeleteDictionaryElement(uint32_t index,
|
| - DeleteMode mode) {
|
| - Isolate* isolate = GetIsolate();
|
| - Heap* heap = isolate->heap();
|
| - FixedArray* backing_store = FixedArray::cast(elements());
|
| - bool is_arguments =
|
| - (GetElementsKind() == JSObject::NON_STRICT_ARGUMENTS_ELEMENTS);
|
| - if (is_arguments) {
|
| - backing_store = FixedArray::cast(backing_store->get(1));
|
| - }
|
| - NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
|
| - int entry = dictionary->FindEntry(index);
|
| - if (entry != NumberDictionary::kNotFound) {
|
| - Object* result = dictionary->DeleteProperty(entry, mode);
|
| - if (result == heap->true_value()) {
|
| - MaybeObject* maybe_elements = dictionary->Shrink(index);
|
| - FixedArray* new_elements = NULL;
|
| - if (!maybe_elements->To(&new_elements)) {
|
| - return maybe_elements;
|
| - }
|
| - if (is_arguments) {
|
| - FixedArray::cast(elements())->set(1, new_elements);
|
| - } else {
|
| - set_elements(new_elements);
|
| - }
|
| - }
|
| - if (mode == STRICT_DELETION && result == heap->false_value()) {
|
| - // In strict mode, attempting to delete a non-configurable property
|
| - // throws an exception.
|
| - HandleScope scope(isolate);
|
| - Handle<Object> holder(this);
|
| - Handle<Object> name = isolate->factory()->NewNumberFromUint(index);
|
| - Handle<Object> args[2] = { name, holder };
|
| - Handle<Object> error =
|
| - isolate->factory()->NewTypeError("strict_delete_property",
|
| - HandleVector(args, 2));
|
| - return isolate->Throw(*error);
|
| - }
|
| - }
|
| - return heap->true_value();
|
| -}
|
| -
|
| -
|
| MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
|
| Isolate* isolate = GetIsolate();
|
| // Check access rights if needed.
|
| @@ -3321,62 +3193,13 @@ MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
|
|
|
| if (HasIndexedInterceptor()) {
|
| // Skip interceptor if forcing deletion.
|
| - return (mode == FORCE_DELETION)
|
| - ? DeleteElementPostInterceptor(index, FORCE_DELETION)
|
| - : DeleteElementWithInterceptor(index);
|
| - }
|
| -
|
| - switch (GetElementsKind()) {
|
| - case FAST_ELEMENTS:
|
| - return DeleteFastElement(index);
|
| -
|
| - case DICTIONARY_ELEMENTS:
|
| - return DeleteDictionaryElement(index, mode);
|
| -
|
| - case FAST_DOUBLE_ELEMENTS: {
|
| - int length = IsJSArray()
|
| - ? Smi::cast(JSArray::cast(this)->length())->value()
|
| - : FixedDoubleArray::cast(elements())->length();
|
| - if (index < static_cast<uint32_t>(length)) {
|
| - FixedDoubleArray::cast(elements())->set_the_hole(index);
|
| - }
|
| - break;
|
| - }
|
| - case EXTERNAL_PIXEL_ELEMENTS:
|
| - case EXTERNAL_BYTE_ELEMENTS:
|
| - case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
|
| - case EXTERNAL_SHORT_ELEMENTS:
|
| - case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
|
| - case EXTERNAL_INT_ELEMENTS:
|
| - case EXTERNAL_UNSIGNED_INT_ELEMENTS:
|
| - case EXTERNAL_FLOAT_ELEMENTS:
|
| - case EXTERNAL_DOUBLE_ELEMENTS:
|
| - // Pixel and external array elements cannot be deleted. Just
|
| - // silently ignore here.
|
| - break;
|
| -
|
| - case NON_STRICT_ARGUMENTS_ELEMENTS: {
|
| - FixedArray* parameter_map = FixedArray::cast(elements());
|
| - uint32_t length = parameter_map->length();
|
| - Object* probe =
|
| - index < (length - 2) ? parameter_map->get(index + 2) : NULL;
|
| - if (probe != NULL && !probe->IsTheHole()) {
|
| - // TODO(kmillikin): We could check if this was the last aliased
|
| - // parameter, and revert to normal elements in that case. That
|
| - // would enable GC of the context.
|
| - parameter_map->set_the_hole(index + 2);
|
| - } else {
|
| - FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
|
| - if (arguments->IsDictionary()) {
|
| - return DeleteDictionaryElement(index, mode);
|
| - } else {
|
| - return DeleteFastElement(index);
|
| - }
|
| - }
|
| - break;
|
| + if (mode != FORCE_DELETION) {
|
| + return DeleteElementWithInterceptor(index);
|
| }
|
| + mode = JSReceiver::FORCE_DELETION;
|
| }
|
| - return isolate->heap()->true_value();
|
| +
|
| + return GetElementsAccessor()->Delete(this, index, mode);
|
| }
|
|
|
|
|
|
|