| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 9333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9344 return this; | 9344 return this; |
| 9345 } | 9345 } |
| 9346 | 9346 |
| 9347 | 9347 |
| 9348 void JSArray::Expand(int required_size) { | 9348 void JSArray::Expand(int required_size) { |
| 9349 GetIsolate()->factory()->SetElementsCapacityAndLength( | 9349 GetIsolate()->factory()->SetElementsCapacityAndLength( |
| 9350 Handle<JSArray>(this), required_size, required_size); | 9350 Handle<JSArray>(this), required_size, required_size); |
| 9351 } | 9351 } |
| 9352 | 9352 |
| 9353 | 9353 |
| 9354 // Returns false if the passed-in index is marked non-configurable, |
| 9355 // which will cause the ES5 truncation operation to halt, and thus |
| 9356 // no further old values need be collected. |
| 9357 static bool GetOldValue(Isolate* isolate, |
| 9358 Handle<JSObject> object, |
| 9359 uint32_t index, |
| 9360 List<Handle<Object> >* old_values, |
| 9361 List<Handle<String> >* indices) { |
| 9362 PropertyAttributes attributes = object->GetLocalElementAttribute(index); |
| 9363 ASSERT(attributes != ABSENT); |
| 9364 if (attributes == DONT_DELETE) return false; |
| 9365 old_values->Add(object->GetLocalElementAccessorPair(index) == NULL |
| 9366 ? Object::GetElement(object, index) |
| 9367 : Handle<Object>::cast(isolate->factory()->the_hole_value())); |
| 9368 indices->Add(isolate->factory()->Uint32ToString(index)); |
| 9369 return true; |
| 9370 } |
| 9371 |
| 9372 |
| 9354 MaybeObject* JSArray::SetElementsLength(Object* len) { | 9373 MaybeObject* JSArray::SetElementsLength(Object* len) { |
| 9355 // We should never end in here with a pixel or external array. | 9374 // We should never end in here with a pixel or external array. |
| 9356 ASSERT(AllowsSetElementsLength()); | 9375 ASSERT(AllowsSetElementsLength()); |
| 9357 if (!(FLAG_harmony_observation && map()->is_observed())) | 9376 if (!(FLAG_harmony_observation && map()->is_observed())) |
| 9358 return GetElementsAccessor()->SetLength(this, len); | 9377 return GetElementsAccessor()->SetLength(this, len); |
| 9359 | 9378 |
| 9360 Isolate* isolate = GetIsolate(); | 9379 Isolate* isolate = GetIsolate(); |
| 9361 HandleScope scope(isolate); | 9380 HandleScope scope(isolate); |
| 9362 Handle<JSArray> self(this); | 9381 Handle<JSArray> self(this); |
| 9363 List<Handle<String> > indices; | 9382 List<Handle<String> > indices; |
| 9364 List<Handle<Object> > old_values; | 9383 List<Handle<Object> > old_values; |
| 9365 Handle<Object> old_length_handle(self->length()); | 9384 Handle<Object> old_length_handle(self->length()); |
| 9366 Handle<Object> new_length_handle(len); | 9385 Handle<Object> new_length_handle(len); |
| 9367 uint32_t old_length = 0; | 9386 uint32_t old_length = 0; |
| 9368 CHECK(old_length_handle->ToArrayIndex(&old_length)); | 9387 CHECK(old_length_handle->ToArrayIndex(&old_length)); |
| 9369 uint32_t new_length = 0; | 9388 uint32_t new_length = 0; |
| 9370 if (!new_length_handle->ToArrayIndex(&new_length)) | 9389 if (!new_length_handle->ToArrayIndex(&new_length)) |
| 9371 return Failure::InternalError(); | 9390 return Failure::InternalError(); |
| 9372 | 9391 |
| 9373 // TODO(adamk): This loop can be very slow for arrays in dictionary mode. | 9392 // Observed arrays should always be in dictionary mode; |
| 9374 // Find another way to iterate over arrays with dictionary elements. | 9393 // if they were in fast mode, the below is slower than necessary |
| 9375 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { | 9394 // as it iterates over the array backing store multiple times. |
| 9376 PropertyAttributes attributes = self->GetLocalElementAttribute(i); | 9395 ASSERT(self->HasDictionaryElements()); |
| 9377 if (attributes == ABSENT) continue; | 9396 static const PropertyAttributes kNoAttrFilter = NONE; |
| 9378 // A non-configurable property will cause the truncation operation to | 9397 int num_elements = self->NumberOfLocalElements(kNoAttrFilter); |
| 9379 // stop at this index. | 9398 if (num_elements > 0) { |
| 9380 if (attributes == DONT_DELETE) break; | 9399 if (old_length == static_cast<uint32_t>(num_elements)) { |
| 9381 old_values.Add( | 9400 // Simple case for arrays without holes. |
| 9382 self->GetLocalElementAccessorPair(i) == NULL | 9401 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { |
| 9383 ? Object::GetElement(self, i) | 9402 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break; |
| 9384 : Handle<Object>::cast(isolate->factory()->the_hole_value())); | 9403 } |
| 9385 indices.Add(isolate->factory()->Uint32ToString(i)); | 9404 } else { |
| 9405 // For sparse arrays, only iterate over existing elements. |
| 9406 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); |
| 9407 self->GetLocalElementKeys(*keys, kNoAttrFilter); |
| 9408 while (num_elements-- > 0) { |
| 9409 uint32_t index = NumberToUint32(keys->get(num_elements)); |
| 9410 if (index < new_length) break; |
| 9411 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break; |
| 9412 } |
| 9413 } |
| 9386 } | 9414 } |
| 9387 | 9415 |
| 9388 MaybeObject* result = | 9416 MaybeObject* result = |
| 9389 self->GetElementsAccessor()->SetLength(*self, *new_length_handle); | 9417 self->GetElementsAccessor()->SetLength(*self, *new_length_handle); |
| 9390 Handle<Object> hresult; | 9418 Handle<Object> hresult; |
| 9391 if (!result->ToHandle(&hresult, isolate)) return result; | 9419 if (!result->ToHandle(&hresult, isolate)) return result; |
| 9392 | 9420 |
| 9393 CHECK(self->length()->ToArrayIndex(&new_length)); | 9421 CHECK(self->length()->ToArrayIndex(&new_length)); |
| 9394 if (old_length != new_length) { | 9422 if (old_length != new_length) { |
| 9395 for (int i = 0; i < indices.length(); ++i) { | 9423 for (int i = 0; i < indices.length(); ++i) { |
| (...skipping 4459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13855 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13883 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
| 13856 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13884 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
| 13857 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13885 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
| 13858 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13886 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
| 13859 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13887 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
| 13860 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13888 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
| 13861 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13889 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
| 13862 } | 13890 } |
| 13863 | 13891 |
| 13864 } } // namespace v8::internal | 13892 } } // namespace v8::internal |
| OLD | NEW |