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 |