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

Side by Side Diff: src/objects.cc

Issue 7901016: Basic support for tracking smi-only arrays on ia32. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix remaining failing tests Created 9 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 2938 matching lines...) Expand 10 before | Expand all | Expand 10 after
2949 FixedArrayBase* array = FixedArrayBase::cast(elements()); 2949 FixedArrayBase* array = FixedArrayBase::cast(elements());
2950 Map* old_map = array->map(); 2950 Map* old_map = array->map();
2951 bool is_arguments = 2951 bool is_arguments =
2952 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map()); 2952 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map());
2953 if (is_arguments) { 2953 if (is_arguments) {
2954 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); 2954 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1));
2955 } 2955 }
2956 if (array->IsDictionary()) return array; 2956 if (array->IsDictionary()) return array;
2957 2957
2958 ASSERT(HasFastElements() || 2958 ASSERT(HasFastElements() ||
2959 HasFastSmiOnlyElements() ||
2959 HasFastDoubleElements() || 2960 HasFastDoubleElements() ||
2960 HasFastArgumentsElements()); 2961 HasFastArgumentsElements());
2961 // Compute the effective length and allocate a new backing store. 2962 // Compute the effective length and allocate a new backing store.
2962 int length = IsJSArray() 2963 int length = IsJSArray()
2963 ? Smi::cast(JSArray::cast(this)->length())->value() 2964 ? Smi::cast(JSArray::cast(this)->length())->value()
2964 : array->length(); 2965 : array->length();
2965 int old_capacity = 0; 2966 int old_capacity = 0;
2966 int used_elements = 0; 2967 int used_elements = 0;
2967 GetElementsCapacityAndUsage(&old_capacity, &used_elements); 2968 GetElementsCapacityAndUsage(&old_capacity, &used_elements);
2968 NumberDictionary* dictionary = NULL; 2969 NumberDictionary* dictionary = NULL;
(...skipping 14 matching lines...) Expand all
2983 } else { 2984 } else {
2984 // Objects must be allocated in the old object space, since the 2985 // Objects must be allocated in the old object space, since the
2985 // overall number of HeapNumbers needed for the conversion might 2986 // overall number of HeapNumbers needed for the conversion might
2986 // exceed the capacity of new space, and we would fail repeatedly 2987 // exceed the capacity of new space, and we would fail repeatedly
2987 // trying to convert the FixedDoubleArray. 2988 // trying to convert the FixedDoubleArray.
2988 MaybeObject* maybe_value_object = 2989 MaybeObject* maybe_value_object =
2989 GetHeap()->AllocateHeapNumber(double_array->get_scalar(i), TENURED); 2990 GetHeap()->AllocateHeapNumber(double_array->get_scalar(i), TENURED);
2990 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; 2991 if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
2991 } 2992 }
2992 } else { 2993 } else {
2993 ASSERT(old_map->has_fast_elements()); 2994 ASSERT(old_map->has_fast_elements() ||
2995 old_map->has_fast_smi_only_elements());
2994 value = FixedArray::cast(array)->get(i); 2996 value = FixedArray::cast(array)->get(i);
2995 } 2997 }
2996 PropertyDetails details = PropertyDetails(NONE, NORMAL); 2998 PropertyDetails details = PropertyDetails(NONE, NORMAL);
2997 if (!value->IsTheHole()) { 2999 if (!value->IsTheHole()) {
2998 Object* result; 3000 Object* result;
2999 MaybeObject* maybe_result = 3001 MaybeObject* maybe_result =
3000 dictionary->AddNumberEntry(i, value, details); 3002 dictionary->AddNumberEntry(i, value, details);
3001 if (!maybe_result->ToObject(&result)) return maybe_result; 3003 if (!maybe_result->ToObject(&result)) return maybe_result;
3002 dictionary = NumberDictionary::cast(result); 3004 dictionary = NumberDictionary::cast(result);
3003 } 3005 }
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
3291 } 3293 }
3292 // Make sure the properties are normalized before removing the entry. 3294 // Make sure the properties are normalized before removing the entry.
3293 return DeleteNormalizedProperty(name, mode); 3295 return DeleteNormalizedProperty(name, mode);
3294 } 3296 }
3295 } 3297 }
3296 3298
3297 3299
3298 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, 3300 bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
3299 ElementsKind kind, 3301 ElementsKind kind,
3300 Object* object) { 3302 Object* object) {
3301 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS); 3303 ASSERT(kind == FAST_ELEMENTS ||
3304 kind == DICTIONARY_ELEMENTS);
3302 if (kind == FAST_ELEMENTS) { 3305 if (kind == FAST_ELEMENTS) {
3303 int length = IsJSArray() 3306 int length = IsJSArray()
3304 ? Smi::cast(JSArray::cast(this)->length())->value() 3307 ? Smi::cast(JSArray::cast(this)->length())->value()
3305 : elements->length(); 3308 : elements->length();
3306 for (int i = 0; i < length; ++i) { 3309 for (int i = 0; i < length; ++i) {
3307 Object* element = elements->get(i); 3310 Object* element = elements->get(i);
3308 if (!element->IsTheHole() && element == object) return true; 3311 if (!element->IsTheHole() && element == object) return true;
3309 } 3312 }
3310 } else { 3313 } else {
3311 Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object); 3314 Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3346 case EXTERNAL_SHORT_ELEMENTS: 3349 case EXTERNAL_SHORT_ELEMENTS:
3347 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3350 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3348 case EXTERNAL_INT_ELEMENTS: 3351 case EXTERNAL_INT_ELEMENTS:
3349 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3352 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3350 case EXTERNAL_FLOAT_ELEMENTS: 3353 case EXTERNAL_FLOAT_ELEMENTS:
3351 case EXTERNAL_DOUBLE_ELEMENTS: 3354 case EXTERNAL_DOUBLE_ELEMENTS:
3352 case FAST_DOUBLE_ELEMENTS: 3355 case FAST_DOUBLE_ELEMENTS:
3353 // Raw pixels and external arrays do not reference other 3356 // Raw pixels and external arrays do not reference other
3354 // objects. 3357 // objects.
3355 break; 3358 break;
3359 case FAST_SMI_ONLY_ELEMENTS:
3360 break;
3356 case FAST_ELEMENTS: 3361 case FAST_ELEMENTS:
3357 case DICTIONARY_ELEMENTS: { 3362 case DICTIONARY_ELEMENTS: {
3358 FixedArray* elements = FixedArray::cast(this->elements()); 3363 FixedArray* elements = FixedArray::cast(this->elements());
3359 if (ReferencesObjectFromElements(elements, kind, obj)) return true; 3364 if (ReferencesObjectFromElements(elements, kind, obj)) return true;
3360 break; 3365 break;
3361 } 3366 }
3362 case NON_STRICT_ARGUMENTS_ELEMENTS: { 3367 case NON_STRICT_ARGUMENTS_ELEMENTS: {
3363 FixedArray* parameter_map = FixedArray::cast(elements()); 3368 FixedArray* parameter_map = FixedArray::cast(elements());
3364 // Check the mapped parameters. 3369 // Check the mapped parameters.
3365 int length = parameter_map->length(); 3370 int length = parameter_map->length();
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
3637 3642
3638 if (!CanSetCallback(name)) { 3643 if (!CanSetCallback(name)) {
3639 return heap->undefined_value(); 3644 return heap->undefined_value();
3640 } 3645 }
3641 3646
3642 uint32_t index = 0; 3647 uint32_t index = 0;
3643 bool is_element = name->AsArrayIndex(&index); 3648 bool is_element = name->AsArrayIndex(&index);
3644 3649
3645 if (is_element) { 3650 if (is_element) {
3646 switch (GetElementsKind()) { 3651 switch (GetElementsKind()) {
3652 case FAST_SMI_ONLY_ELEMENTS:
3647 case FAST_ELEMENTS: 3653 case FAST_ELEMENTS:
3648 case FAST_DOUBLE_ELEMENTS: 3654 case FAST_DOUBLE_ELEMENTS:
3649 break; 3655 break;
3650 case EXTERNAL_PIXEL_ELEMENTS: 3656 case EXTERNAL_PIXEL_ELEMENTS:
3651 case EXTERNAL_BYTE_ELEMENTS: 3657 case EXTERNAL_BYTE_ELEMENTS:
3652 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3658 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3653 case EXTERNAL_SHORT_ELEMENTS: 3659 case EXTERNAL_SHORT_ELEMENTS:
3654 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3660 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3655 case EXTERNAL_INT_ELEMENTS: 3661 case EXTERNAL_INT_ELEMENTS:
3656 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3662 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
3886 } 3892 }
3887 3893
3888 uint32_t index = 0; 3894 uint32_t index = 0;
3889 bool is_element = name->AsArrayIndex(&index); 3895 bool is_element = name->AsArrayIndex(&index);
3890 3896
3891 if (is_element) { 3897 if (is_element) {
3892 if (IsJSArray()) return isolate->heap()->undefined_value(); 3898 if (IsJSArray()) return isolate->heap()->undefined_value();
3893 3899
3894 // Accessors overwrite previous callbacks (cf. with getters/setters). 3900 // Accessors overwrite previous callbacks (cf. with getters/setters).
3895 switch (GetElementsKind()) { 3901 switch (GetElementsKind()) {
3902 case FAST_SMI_ONLY_ELEMENTS:
3896 case FAST_ELEMENTS: 3903 case FAST_ELEMENTS:
3897 case FAST_DOUBLE_ELEMENTS: 3904 case FAST_DOUBLE_ELEMENTS:
3898 break; 3905 break;
3899 case EXTERNAL_PIXEL_ELEMENTS: 3906 case EXTERNAL_PIXEL_ELEMENTS:
3900 case EXTERNAL_BYTE_ELEMENTS: 3907 case EXTERNAL_BYTE_ELEMENTS:
3901 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3908 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3902 case EXTERNAL_SHORT_ELEMENTS: 3909 case EXTERNAL_SHORT_ELEMENTS:
3903 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3910 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3904 case EXTERNAL_INT_ELEMENTS: 3911 case EXTERNAL_INT_ELEMENTS:
3905 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3912 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
(...skipping 3389 matching lines...) Expand 10 before | Expand all | Expand 10 after
7295 for (int i = 0; i < source->Capacity(); ++i) { 7302 for (int i = 0; i < source->Capacity(); ++i) {
7296 Object* key = source->KeyAt(i); 7303 Object* key = source->KeyAt(i);
7297 if (key->IsNumber()) { 7304 if (key->IsNumber()) {
7298 uint32_t entry = static_cast<uint32_t>(key->Number()); 7305 uint32_t entry = static_cast<uint32_t>(key->Number());
7299 destination->set(entry, source->ValueAt(i), mode); 7306 destination->set(entry, source->ValueAt(i), mode);
7300 } 7307 }
7301 } 7308 }
7302 } 7309 }
7303 7310
7304 7311
7305 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity, 7312 MaybeObject* JSObject::SetFastElementsCapacityAndLength(
7306 int length) { 7313 int capacity,
7314 int length,
7315 SetFastElementsCapacityMode set_capacity_mode) {
7307 Heap* heap = GetHeap(); 7316 Heap* heap = GetHeap();
7308 // We should never end in here with a pixel or external array. 7317 // We should never end in here with a pixel or external array.
7309 ASSERT(!HasExternalArrayElements()); 7318 ASSERT(!HasExternalArrayElements());
7310 7319
7311 // Allocate a new fast elements backing store. 7320 // Allocate a new fast elements backing store.
7312 FixedArray* new_elements = NULL; 7321 FixedArray* new_elements = NULL;
7313 { Object* object; 7322 { Object* object;
7314 MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity); 7323 MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity);
7315 if (!maybe->ToObject(&object)) return maybe; 7324 if (!maybe->ToObject(&object)) return maybe;
7316 new_elements = FixedArray::cast(object); 7325 new_elements = FixedArray::cast(object);
7317 } 7326 }
7318 7327
7319 // Find the new map to use for this object if there is a map change. 7328 // Find the new map to use for this object if there is a map change.
7320 Map* new_map = NULL; 7329 Map* new_map = NULL;
7321 if (elements()->map() != heap->non_strict_arguments_elements_map()) { 7330 if (elements()->map() != heap->non_strict_arguments_elements_map()) {
7322 Object* object; 7331 Object* object;
7323 MaybeObject* maybe = GetElementsTransitionMap(FAST_ELEMENTS); 7332 bool has_fast_smi_only_elements =
7333 FLAG_smi_only_arrays &&
7334 (set_capacity_mode == kAllowSmiOnlyElements) &&
7335 (elements()->map()->has_fast_smi_only_elements() ||
7336 elements() == heap->empty_fixed_array());
7337 ElementsKind elements_kind = has_fast_smi_only_elements
7338 ? FAST_SMI_ONLY_ELEMENTS
7339 : FAST_ELEMENTS;
7340 MaybeObject* maybe = GetElementsTransitionMap(elements_kind);
7324 if (!maybe->ToObject(&object)) return maybe; 7341 if (!maybe->ToObject(&object)) return maybe;
7325 new_map = Map::cast(object); 7342 new_map = Map::cast(object);
7326 } 7343 }
7327 7344
7328 switch (GetElementsKind()) { 7345 ElementsKind elements_kind = GetElementsKind();
7346 switch (elements_kind) {
7347 case FAST_SMI_ONLY_ELEMENTS:
7329 case FAST_ELEMENTS: { 7348 case FAST_ELEMENTS: {
7330 AssertNoAllocation no_gc; 7349 AssertNoAllocation no_gc;
7331 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); 7350 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc));
7332 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode); 7351 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode);
7333 set_map(new_map); 7352 set_map(new_map);
7334 set_elements(new_elements); 7353 set_elements(new_elements);
7335 break; 7354 break;
7336 } 7355 }
7337 case DICTIONARY_ELEMENTS: { 7356 case DICTIONARY_ELEMENTS: {
7338 AssertNoAllocation no_gc; 7357 AssertNoAllocation no_gc;
7339 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); 7358 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7340 CopySlowElementsToFast(NumberDictionary::cast(elements()), 7359 CopySlowElementsToFast(NumberDictionary::cast(elements()),
7341 new_elements, 7360 new_elements,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
7424 FixedDoubleArray* elems = FixedDoubleArray::cast(obj); 7443 FixedDoubleArray* elems = FixedDoubleArray::cast(obj);
7425 7444
7426 { MaybeObject* maybe_obj = 7445 { MaybeObject* maybe_obj =
7427 GetElementsTransitionMap(FAST_DOUBLE_ELEMENTS); 7446 GetElementsTransitionMap(FAST_DOUBLE_ELEMENTS);
7428 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7447 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7429 } 7448 }
7430 Map* new_map = Map::cast(obj); 7449 Map* new_map = Map::cast(obj);
7431 7450
7432 AssertNoAllocation no_gc; 7451 AssertNoAllocation no_gc;
7433 switch (GetElementsKind()) { 7452 switch (GetElementsKind()) {
7453 case FAST_SMI_ONLY_ELEMENTS:
7434 case FAST_ELEMENTS: { 7454 case FAST_ELEMENTS: {
7435 elems->Initialize(FixedArray::cast(elements())); 7455 elems->Initialize(FixedArray::cast(elements()));
7436 break; 7456 break;
7437 } 7457 }
7438 case FAST_DOUBLE_ELEMENTS: { 7458 case FAST_DOUBLE_ELEMENTS: {
7439 elems->Initialize(FixedDoubleArray::cast(elements())); 7459 elems->Initialize(FixedDoubleArray::cast(elements()));
7440 break; 7460 break;
7441 } 7461 }
7442 case DICTIONARY_ELEMENTS: { 7462 case DICTIONARY_ELEMENTS: {
7443 elems->Initialize(NumberDictionary::cast(elements())); 7463 elems->Initialize(NumberDictionary::cast(elements()));
(...skipping 17 matching lines...) Expand all
7461 } 7481 }
7462 7482
7463 7483
7464 MaybeObject* JSObject::SetSlowElements(Object* len) { 7484 MaybeObject* JSObject::SetSlowElements(Object* len) {
7465 // We should never end in here with a pixel or external array. 7485 // We should never end in here with a pixel or external array.
7466 ASSERT(!HasExternalArrayElements()); 7486 ASSERT(!HasExternalArrayElements());
7467 7487
7468 uint32_t new_length = static_cast<uint32_t>(len->Number()); 7488 uint32_t new_length = static_cast<uint32_t>(len->Number());
7469 7489
7470 switch (GetElementsKind()) { 7490 switch (GetElementsKind()) {
7471 case FAST_ELEMENTS: { 7491 case FAST_SMI_ONLY_ELEMENTS:
7472 case FAST_DOUBLE_ELEMENTS: 7492 case FAST_ELEMENTS:
7493 case FAST_DOUBLE_ELEMENTS: {
7473 // Make sure we never try to shrink dense arrays into sparse arrays. 7494 // Make sure we never try to shrink dense arrays into sparse arrays.
7474 ASSERT(static_cast<uint32_t>( 7495 ASSERT(static_cast<uint32_t>(
7475 FixedArrayBase::cast(elements())->length()) <= new_length); 7496 FixedArrayBase::cast(elements())->length()) <= new_length);
7476 MaybeObject* result = NormalizeElements(); 7497 MaybeObject* result = NormalizeElements();
7477 if (result->IsFailure()) return result; 7498 if (result->IsFailure()) return result;
7478 7499
7479 // Update length for JSArrays. 7500 // Update length for JSArrays.
7480 if (IsJSArray()) JSArray::cast(this)->set_length(len); 7501 if (IsJSArray()) JSArray::cast(this)->set_length(len);
7481 break; 7502 break;
7482 } 7503 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
7528 7549
7529 7550
7530 void JSArray::Expand(int required_size) { 7551 void JSArray::Expand(int required_size) {
7531 Handle<JSArray> self(this); 7552 Handle<JSArray> self(this);
7532 Handle<FixedArray> old_backing(FixedArray::cast(elements())); 7553 Handle<FixedArray> old_backing(FixedArray::cast(elements()));
7533 int old_size = old_backing->length(); 7554 int old_size = old_backing->length();
7534 int new_size = required_size > old_size ? required_size : old_size; 7555 int new_size = required_size > old_size ? required_size : old_size;
7535 Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size); 7556 Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size);
7536 // Can't use this any more now because we may have had a GC! 7557 // Can't use this any more now because we may have had a GC!
7537 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); 7558 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i));
7538 self->SetContent(*new_backing); 7559 GetIsolate()->factory()->SetContent(self, new_backing);
7539 } 7560 }
7540 7561
7541 7562
7542 static Failure* ArrayLengthRangeError(Heap* heap) { 7563 static Failure* ArrayLengthRangeError(Heap* heap) {
7543 HandleScope scope(heap->isolate()); 7564 HandleScope scope(heap->isolate());
7544 return heap->isolate()->Throw( 7565 return heap->isolate()->Throw(
7545 *FACTORY->NewRangeError("invalid_array_length", 7566 *FACTORY->NewRangeError("invalid_array_length",
7546 HandleVector<Object>(NULL, 0))); 7567 HandleVector<Object>(NULL, 0)));
7547 } 7568 }
7548 7569
7549 7570
7550 MaybeObject* JSObject::SetElementsLength(Object* len) { 7571 MaybeObject* JSObject::SetElementsLength(Object* len) {
7551 // We should never end in here with a pixel or external array. 7572 // We should never end in here with a pixel or external array.
7552 ASSERT(AllowsSetElementsLength()); 7573 ASSERT(AllowsSetElementsLength());
7553 7574
7554 MaybeObject* maybe_smi_length = len->ToSmi(); 7575 MaybeObject* maybe_smi_length = len->ToSmi();
7555 Object* smi_length = Smi::FromInt(0); 7576 Object* smi_length = Smi::FromInt(0);
7556 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { 7577 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) {
7557 const int value = Smi::cast(smi_length)->value(); 7578 const int value = Smi::cast(smi_length)->value();
7558 if (value < 0) return ArrayLengthRangeError(GetHeap()); 7579 if (value < 0) return ArrayLengthRangeError(GetHeap());
7559 ElementsKind elements_kind = GetElementsKind(); 7580 ElementsKind elements_kind = GetElementsKind();
7560 switch (elements_kind) { 7581 switch (elements_kind) {
7582 case FAST_SMI_ONLY_ELEMENTS:
7561 case FAST_ELEMENTS: 7583 case FAST_ELEMENTS:
7562 case FAST_DOUBLE_ELEMENTS: { 7584 case FAST_DOUBLE_ELEMENTS: {
7563 int old_capacity = FixedArrayBase::cast(elements())->length(); 7585 int old_capacity = FixedArrayBase::cast(elements())->length();
7564 if (value <= old_capacity) { 7586 if (value <= old_capacity) {
7565 if (IsJSArray()) { 7587 if (IsJSArray()) {
7566 Object* obj; 7588 Object* obj;
7567 if (elements_kind == FAST_ELEMENTS) { 7589 if (elements_kind != FAST_DOUBLE_ELEMENTS) {
fschneider 2011/09/22 07:46:38 Maybe make the condition consistent with the other
danno 2011/09/22 11:23:15 Done.
7590 ASSERT(elements_kind == FAST_ELEMENTS ||
7591 elements_kind == FAST_SMI_ONLY_ELEMENTS);
7568 MaybeObject* maybe_obj = EnsureWritableFastElements(); 7592 MaybeObject* maybe_obj = EnsureWritableFastElements();
7569 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7593 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7570 } 7594 }
7571 if (2 * value <= old_capacity) { 7595 if (2 * value <= old_capacity) {
7572 // If more than half the elements won't be used, trim the array. 7596 // If more than half the elements won't be used, trim the array.
7573 if (value == 0) { 7597 if (value == 0) {
7574 initialize_elements(); 7598 initialize_elements();
7575 } else { 7599 } else {
7576 Address filler_start; 7600 Address filler_start;
7577 int filler_size; 7601 int filler_size;
7578 if (GetElementsKind() == FAST_ELEMENTS) { 7602 if (elements_kind == FAST_ELEMENTS ||
7603 elements_kind == FAST_SMI_ONLY_ELEMENTS) {
7579 FixedArray* fast_elements = FixedArray::cast(elements()); 7604 FixedArray* fast_elements = FixedArray::cast(elements());
7580 fast_elements->set_length(value); 7605 fast_elements->set_length(value);
7581 filler_start = fast_elements->address() + 7606 filler_start = fast_elements->address() +
7582 FixedArray::OffsetOfElementAt(value); 7607 FixedArray::OffsetOfElementAt(value);
7583 filler_size = (old_capacity - value) * kPointerSize; 7608 filler_size = (old_capacity - value) * kPointerSize;
7584 } else { 7609 } else {
7585 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS); 7610 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS);
7586 FixedDoubleArray* fast_double_elements = 7611 FixedDoubleArray* fast_double_elements =
7587 FixedDoubleArray::cast(elements()); 7612 FixedDoubleArray::cast(elements());
7588 fast_double_elements->set_length(value); 7613 fast_double_elements->set_length(value);
7589 filler_start = fast_double_elements->address() + 7614 filler_start = fast_double_elements->address() +
7590 FixedDoubleArray::OffsetOfElementAt(value); 7615 FixedDoubleArray::OffsetOfElementAt(value);
7591 filler_size = (old_capacity - value) * kDoubleSize; 7616 filler_size = (old_capacity - value) * kDoubleSize;
7592 } 7617 }
7593 GetHeap()->CreateFillerObjectAt(filler_start, filler_size); 7618 GetHeap()->CreateFillerObjectAt(filler_start, filler_size);
7594 } 7619 }
7595 } else { 7620 } else {
7596 // Otherwise, fill the unused tail with holes. 7621 // Otherwise, fill the unused tail with holes.
7597 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); 7622 int old_length = FastD2I(JSArray::cast(this)->length()->Number());
7598 if (GetElementsKind() == FAST_ELEMENTS) { 7623 if (elements_kind == FAST_ELEMENTS ||
7624 elements_kind == FAST_SMI_ONLY_ELEMENTS) {
7599 FixedArray* fast_elements = FixedArray::cast(elements()); 7625 FixedArray* fast_elements = FixedArray::cast(elements());
7600 for (int i = value; i < old_length; i++) { 7626 for (int i = value; i < old_length; i++) {
7601 fast_elements->set_the_hole(i); 7627 fast_elements->set_the_hole(i);
7602 } 7628 }
7603 } else { 7629 } else {
7604 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS); 7630 ASSERT(elements_kind == FAST_DOUBLE_ELEMENTS);
7605 FixedDoubleArray* fast_double_elements = 7631 FixedDoubleArray* fast_double_elements =
7606 FixedDoubleArray::cast(elements()); 7632 FixedDoubleArray::cast(elements());
7607 for (int i = value; i < old_length; i++) { 7633 for (int i = value; i < old_length; i++) {
7608 fast_double_elements->set_the_hole(i); 7634 fast_double_elements->set_the_hole(i);
7609 } 7635 }
7610 } 7636 }
7611 } 7637 }
7612 JSArray::cast(this)->set_length(Smi::cast(smi_length)); 7638 JSArray::cast(this)->set_length(Smi::cast(smi_length));
7613 } 7639 }
7614 return this; 7640 return this;
7615 } 7641 }
7616 int min = NewElementsCapacity(old_capacity); 7642 int min = NewElementsCapacity(old_capacity);
7617 int new_capacity = value > min ? value : min; 7643 int new_capacity = value > min ? value : min;
7618 if (!ShouldConvertToSlowElements(new_capacity)) { 7644 if (!ShouldConvertToSlowElements(new_capacity)) {
7619 MaybeObject* result; 7645 MaybeObject* result;
7620 if (GetElementsKind() == FAST_ELEMENTS) { 7646 if (elements_kind == FAST_ELEMENTS ||
7621 result = SetFastElementsCapacityAndLength(new_capacity, value); 7647 elements_kind == FAST_SMI_ONLY_ELEMENTS) {
7648 SetFastElementsCapacityMode set_capacity_mode =
7649 elements_kind == FAST_SMI_ONLY_ELEMENTS
7650 ? kAllowSmiOnlyElements
7651 : kDontAllowSmiOnlyElements;
7652 result = SetFastElementsCapacityAndLength(new_capacity,
7653 value,
7654 set_capacity_mode);
7622 } else { 7655 } else {
7623 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS); 7656 ASSERT(elements_kind == FAST_DOUBLE_ELEMENTS);
7624 result = SetFastDoubleElementsCapacityAndLength(new_capacity, 7657 result = SetFastDoubleElementsCapacityAndLength(new_capacity,
7625 value); 7658 value);
7626 } 7659 }
7627 if (result->IsFailure()) return result; 7660 if (result->IsFailure()) return result;
7628 return this; 7661 return this;
7629 } 7662 }
7630 break; 7663 break;
7631 } 7664 }
7632 case DICTIONARY_ELEMENTS: { 7665 case DICTIONARY_ELEMENTS: {
7633 if (IsJSArray()) { 7666 if (IsJSArray()) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
7670 if (len->ToArrayIndex(&length)) { 7703 if (len->ToArrayIndex(&length)) {
7671 return SetSlowElements(len); 7704 return SetSlowElements(len);
7672 } else { 7705 } else {
7673 return ArrayLengthRangeError(GetHeap()); 7706 return ArrayLengthRangeError(GetHeap());
7674 } 7707 }
7675 } 7708 }
7676 7709
7677 // len is not a number so make the array size one and 7710 // len is not a number so make the array size one and
7678 // set only element to len. 7711 // set only element to len.
7679 Object* obj; 7712 Object* obj;
7680 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(1); 7713 MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(1);
7681 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7714 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7682 }
7683 FixedArray::cast(obj)->set(0, len); 7715 FixedArray::cast(obj)->set(0, len);
7716
7717 maybe_obj = EnsureCanContainElements(&len, 1);
7718 if (maybe_obj->IsFailure()) return maybe_obj;
7719
7684 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); 7720 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1));
7685 set_elements(FixedArray::cast(obj)); 7721 set_elements(FixedArray::cast(obj));
7686 return this; 7722 return this;
7687 } 7723 }
7688 7724
7689 7725
7690 Object* Map::GetPrototypeTransition(Object* prototype) { 7726 Object* Map::GetPrototypeTransition(Object* prototype) {
7691 FixedArray* cache = prototype_transitions(); 7727 FixedArray* cache = prototype_transitions();
7692 int number_of_transitions = NumberOfProtoTransitions(); 7728 int number_of_transitions = NumberOfProtoTransitions();
7693 const int proto_offset = 7729 const int proto_offset =
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
7821 } 7857 }
7822 ASSERT(Map::cast(new_map)->prototype() == value); 7858 ASSERT(Map::cast(new_map)->prototype() == value);
7823 real_receiver->set_map(Map::cast(new_map)); 7859 real_receiver->set_map(Map::cast(new_map));
7824 7860
7825 heap->ClearInstanceofCache(); 7861 heap->ClearInstanceofCache();
7826 ASSERT(size == Size()); 7862 ASSERT(size == Size());
7827 return value; 7863 return value;
7828 } 7864 }
7829 7865
7830 7866
7867 MaybeObject* JSObject::EnsureCanContainElements(Arguments* args,
7868 uint32_t first_arg,
7869 uint32_t arg_count) {
7870 return EnsureCanContainElements(args->arguments() - first_arg, arg_count);
7871 }
7872
7873
7831 bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) { 7874 bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) {
7832 switch (GetElementsKind()) { 7875 switch (GetElementsKind()) {
7876 case FAST_SMI_ONLY_ELEMENTS:
7833 case FAST_ELEMENTS: { 7877 case FAST_ELEMENTS: {
7834 uint32_t length = IsJSArray() ? 7878 uint32_t length = IsJSArray() ?
7835 static_cast<uint32_t> 7879 static_cast<uint32_t>
7836 (Smi::cast(JSArray::cast(this)->length())->value()) : 7880 (Smi::cast(JSArray::cast(this)->length())->value()) :
7837 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 7881 static_cast<uint32_t>(FixedArray::cast(elements())->length());
7838 if ((index < length) && 7882 if ((index < length) &&
7839 !FixedArray::cast(elements())->get(index)->IsTheHole()) { 7883 !FixedArray::cast(elements())->get(index)->IsTheHole()) {
7840 return true; 7884 return true;
7841 } 7885 }
7842 break; 7886 break;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
7959 return HasElementWithInterceptor(this, index) ? INTERCEPTED_ELEMENT 8003 return HasElementWithInterceptor(this, index) ? INTERCEPTED_ELEMENT
7960 : UNDEFINED_ELEMENT; 8004 : UNDEFINED_ELEMENT;
7961 } 8005 }
7962 8006
7963 // Handle [] on String objects. 8007 // Handle [] on String objects.
7964 if (this->IsStringObjectWithCharacterAt(index)) { 8008 if (this->IsStringObjectWithCharacterAt(index)) {
7965 return STRING_CHARACTER_ELEMENT; 8009 return STRING_CHARACTER_ELEMENT;
7966 } 8010 }
7967 8011
7968 switch (GetElementsKind()) { 8012 switch (GetElementsKind()) {
8013 case FAST_SMI_ONLY_ELEMENTS:
7969 case FAST_ELEMENTS: { 8014 case FAST_ELEMENTS: {
7970 uint32_t length = IsJSArray() ? 8015 uint32_t length = IsJSArray() ?
7971 static_cast<uint32_t> 8016 static_cast<uint32_t>
7972 (Smi::cast(JSArray::cast(this)->length())->value()) : 8017 (Smi::cast(JSArray::cast(this)->length())->value()) :
7973 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 8018 static_cast<uint32_t>(FixedArray::cast(elements())->length());
7974 if ((index < length) && 8019 if ((index < length) &&
7975 !FixedArray::cast(elements())->get(index)->IsTheHole()) { 8020 !FixedArray::cast(elements())->get(index)->IsTheHole()) {
7976 return FAST_ELEMENT; 8021 return FAST_ELEMENT;
7977 } 8022 }
7978 break; 8023 break;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
8073 } 8118 }
8074 } 8119 }
8075 8120
8076 // Check for lookup interceptor 8121 // Check for lookup interceptor
8077 if (HasIndexedInterceptor()) { 8122 if (HasIndexedInterceptor()) {
8078 return HasElementWithInterceptor(receiver, index); 8123 return HasElementWithInterceptor(receiver, index);
8079 } 8124 }
8080 8125
8081 ElementsKind kind = GetElementsKind(); 8126 ElementsKind kind = GetElementsKind();
8082 switch (kind) { 8127 switch (kind) {
8128 case FAST_SMI_ONLY_ELEMENTS:
8083 case FAST_ELEMENTS: { 8129 case FAST_ELEMENTS: {
8084 uint32_t length = IsJSArray() ? 8130 uint32_t length = IsJSArray() ?
8085 static_cast<uint32_t> 8131 static_cast<uint32_t>
8086 (Smi::cast(JSArray::cast(this)->length())->value()) : 8132 (Smi::cast(JSArray::cast(this)->length())->value()) :
8087 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 8133 static_cast<uint32_t>(FixedArray::cast(elements())->length());
8088 if ((index < length) && 8134 if ((index < length) &&
8089 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true; 8135 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true;
8090 break; 8136 break;
8091 } 8137 }
8092 case FAST_DOUBLE_ELEMENTS: { 8138 case FAST_DOUBLE_ELEMENTS: {
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
8323 } 8369 }
8324 8370
8325 8371
8326 // Adding n elements in fast case is O(n*n). 8372 // Adding n elements in fast case is O(n*n).
8327 // Note: revisit design to have dual undefined values to capture absent 8373 // Note: revisit design to have dual undefined values to capture absent
8328 // elements. 8374 // elements.
8329 MaybeObject* JSObject::SetFastElement(uint32_t index, 8375 MaybeObject* JSObject::SetFastElement(uint32_t index,
8330 Object* value, 8376 Object* value,
8331 StrictModeFlag strict_mode, 8377 StrictModeFlag strict_mode,
8332 bool check_prototype) { 8378 bool check_prototype) {
8333 ASSERT(HasFastElements() || HasFastArgumentsElements()); 8379 ASSERT(HasFastTypeElements() ||
8380 HasFastArgumentsElements());
8334 8381
8335 FixedArray* backing_store = FixedArray::cast(elements()); 8382 FixedArray* backing_store = FixedArray::cast(elements());
8336 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) { 8383 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) {
8337 backing_store = FixedArray::cast(backing_store->get(1)); 8384 backing_store = FixedArray::cast(backing_store->get(1));
8338 } else { 8385 } else {
8339 Object* writable; 8386 Object* writable;
8340 MaybeObject* maybe = EnsureWritableFastElements(); 8387 MaybeObject* maybe = EnsureWritableFastElements();
8341 if (!maybe->ToObject(&writable)) return maybe; 8388 if (!maybe->ToObject(&writable)) return maybe;
8342 backing_store = FixedArray::cast(writable); 8389 backing_store = FixedArray::cast(writable);
8343 } 8390 }
8344 uint32_t length = static_cast<uint32_t>(backing_store->length()); 8391 uint32_t length = static_cast<uint32_t>(backing_store->length());
8345 8392
8346 if (check_prototype && 8393 if (check_prototype &&
8347 (index >= length || backing_store->get(index)->IsTheHole())) { 8394 (index >= length || backing_store->get(index)->IsTheHole())) {
8348 bool found; 8395 bool found;
8349 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, 8396 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index,
8350 value, 8397 value,
8351 &found, 8398 &found,
8352 strict_mode); 8399 strict_mode);
8353 if (found) return result; 8400 if (found) return result;
8354 } 8401 }
8355 8402
8356 // Check whether there is extra space in fixed array. 8403 // Check whether there is extra space in fixed array.
8357 if (index < length) { 8404 if (index < length) {
8405 if (HasFastSmiOnlyElements()) {
8406 if (!value->IsSmi()) {
8407 // If the value is a number, transition from smi-only to
8408 // FastDoubleElements.
8409 if (value->IsNumber()) {
8410 MaybeObject* maybe =
8411 SetFastDoubleElementsCapacityAndLength(length, length);
8412 if (maybe->IsFailure()) return maybe;
8413 FixedDoubleArray::cast(elements())->set(index, value->Number());
8414 return value;
8415 }
8416 // Value is not a number, transition to generic fast elements.
8417 MaybeObject* maybe_new_map = GetElementsTransitionMap(FAST_ELEMENTS);
8418 Map* new_map;
8419 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map;
8420 set_map(new_map);
8421 }
8422 }
8358 backing_store->set(index, value); 8423 backing_store->set(index, value);
8359 if (IsJSArray()) { 8424 if (IsJSArray()) {
8360 // Update the length of the array if needed. 8425 // Update the length of the array if needed.
8361 uint32_t array_length = 0; 8426 uint32_t array_length = 0;
8362 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); 8427 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length));
8363 if (index >= array_length) { 8428 if (index >= array_length) {
8364 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); 8429 JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
8365 } 8430 }
8366 } 8431 }
8367 return value; 8432 return value;
8368 } 8433 }
8369 8434
8370 // Allow gap in fast case. 8435 // Allow gap in fast case.
8371 if ((index - length) < kMaxGap) { 8436 if ((index - length) < kMaxGap) {
8372 // Try allocating extra space. 8437 // Try allocating extra space.
8373 int new_capacity = NewElementsCapacity(index + 1); 8438 int new_capacity = NewElementsCapacity(index + 1);
8374 if (!ShouldConvertToSlowElements(new_capacity)) { 8439 if (!ShouldConvertToSlowElements(new_capacity)) {
8375 ASSERT(static_cast<uint32_t>(new_capacity) > index); 8440 ASSERT(static_cast<uint32_t>(new_capacity) > index);
8376 Object* new_elements; 8441 Object* new_elements;
8442 SetFastElementsCapacityMode set_capacity_mode =
8443 value->IsSmi() && HasFastSmiOnlyElements()
8444 ? kAllowSmiOnlyElements
8445 : kDontAllowSmiOnlyElements;
8377 MaybeObject* maybe = 8446 MaybeObject* maybe =
8378 SetFastElementsCapacityAndLength(new_capacity, index + 1); 8447 SetFastElementsCapacityAndLength(new_capacity,
8448 index + 1,
8449 set_capacity_mode);
8379 if (!maybe->ToObject(&new_elements)) return maybe; 8450 if (!maybe->ToObject(&new_elements)) return maybe;
8380 FixedArray::cast(new_elements)->set(index, value); 8451 FixedArray::cast(new_elements)->set(index, value);
8381 return value; 8452 return value;
8382 } 8453 }
8383 } 8454 }
8384 8455
8385 // Otherwise default to slow case. 8456 // Otherwise default to slow case.
8386 MaybeObject* result = NormalizeElements(); 8457 MaybeObject* result = NormalizeElements();
8387 if (result->IsFailure()) return result; 8458 if (result->IsFailure()) return result;
8388 return SetDictionaryElement(index, value, strict_mode, check_prototype); 8459 return SetDictionaryElement(index, value, strict_mode, check_prototype);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
8474 // Attempt to put this object back in fast case. 8545 // Attempt to put this object back in fast case.
8475 if (ShouldConvertToFastElements()) { 8546 if (ShouldConvertToFastElements()) {
8476 uint32_t new_length = 0; 8547 uint32_t new_length = 0;
8477 if (IsJSArray()) { 8548 if (IsJSArray()) {
8478 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); 8549 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length));
8479 } else { 8550 } else {
8480 new_length = dictionary->max_number_key() + 1; 8551 new_length = dictionary->max_number_key() + 1;
8481 } 8552 }
8482 MaybeObject* result = CanConvertToFastDoubleElements() 8553 MaybeObject* result = CanConvertToFastDoubleElements()
8483 ? SetFastDoubleElementsCapacityAndLength(new_length, new_length) 8554 ? SetFastDoubleElementsCapacityAndLength(new_length, new_length)
8484 : SetFastElementsCapacityAndLength(new_length, new_length); 8555 : SetFastElementsCapacityAndLength(new_length,
8556 new_length,
8557 kDontAllowSmiOnlyElements);
8485 if (result->IsFailure()) return result; 8558 if (result->IsFailure()) return result;
8486 #ifdef DEBUG 8559 #ifdef DEBUG
8487 if (FLAG_trace_normalization) { 8560 if (FLAG_trace_normalization) {
8488 PrintF("Object elements are fast case again:\n"); 8561 PrintF("Object elements are fast case again:\n");
8489 Print(); 8562 Print();
8490 } 8563 }
8491 #endif 8564 #endif
8492 } 8565 }
8493 return value; 8566 return value;
8494 } 8567 }
(...skipping 23 matching lines...) Expand all
8518 8591
8519 // If the value object is not a heap number, switch to fast elements and try 8592 // If the value object is not a heap number, switch to fast elements and try
8520 // again. 8593 // again.
8521 bool value_is_smi = value->IsSmi(); 8594 bool value_is_smi = value->IsSmi();
8522 if (!value->IsNumber()) { 8595 if (!value->IsNumber()) {
8523 Object* obj; 8596 Object* obj;
8524 uint32_t length = elms_length; 8597 uint32_t length = elms_length;
8525 if (IsJSArray()) { 8598 if (IsJSArray()) {
8526 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); 8599 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length));
8527 } 8600 }
8528 MaybeObject* maybe_obj = 8601 MaybeObject* maybe_obj = SetFastElementsCapacityAndLength(
8529 SetFastElementsCapacityAndLength(elms_length, length); 8602 elms_length,
8603 length,
8604 kDontAllowSmiOnlyElements);
8530 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8605 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8531 return SetFastElement(index, value, strict_mode, check_prototype); 8606 return SetFastElement(index,
8607 value,
8608 strict_mode,
8609 check_prototype);
8532 } 8610 }
8533 8611
8534 double double_value = value_is_smi 8612 double double_value = value_is_smi
8535 ? static_cast<double>(Smi::cast(value)->value()) 8613 ? static_cast<double>(Smi::cast(value)->value())
8536 : HeapNumber::cast(value)->value(); 8614 : HeapNumber::cast(value)->value();
8537 8615
8538 // Check whether there is extra space in the fixed array. 8616 // Check whether there is extra space in the fixed array.
8539 if (index < elms_length) { 8617 if (index < elms_length) {
8540 elms->set(index, double_value); 8618 elms->set(index, double_value);
8541 if (IsJSArray()) { 8619 if (IsJSArray()) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
8618 check_prototype); 8696 check_prototype);
8619 } 8697 }
8620 8698
8621 8699
8622 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, 8700 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index,
8623 Object* value, 8701 Object* value,
8624 StrictModeFlag strict_mode, 8702 StrictModeFlag strict_mode,
8625 bool check_prototype) { 8703 bool check_prototype) {
8626 Isolate* isolate = GetIsolate(); 8704 Isolate* isolate = GetIsolate();
8627 switch (GetElementsKind()) { 8705 switch (GetElementsKind()) {
8706 case FAST_SMI_ONLY_ELEMENTS:
8628 case FAST_ELEMENTS: 8707 case FAST_ELEMENTS:
8629 return SetFastElement(index, value, strict_mode, check_prototype); 8708 return SetFastElement(index, value, strict_mode, check_prototype);
8630 case FAST_DOUBLE_ELEMENTS: 8709 case FAST_DOUBLE_ELEMENTS:
8631 return SetFastDoubleElement(index, value, strict_mode, check_prototype); 8710 return SetFastDoubleElement(index, value, strict_mode, check_prototype);
8632 case EXTERNAL_PIXEL_ELEMENTS: { 8711 case EXTERNAL_PIXEL_ELEMENTS: {
8633 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); 8712 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
8634 return pixels->SetValue(index, value); 8713 return pixels->SetValue(index, value);
8635 } 8714 }
8636 case EXTERNAL_BYTE_ELEMENTS: { 8715 case EXTERNAL_BYTE_ELEMENTS: {
8637 ExternalByteArray* array = ExternalByteArray::cast(elements()); 8716 ExternalByteArray* array = ExternalByteArray::cast(elements());
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
8780 backing_store_base = 8859 backing_store_base =
8781 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); 8860 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1));
8782 backing_store = FixedArray::cast(backing_store_base); 8861 backing_store = FixedArray::cast(backing_store_base);
8783 if (backing_store->IsDictionary()) { 8862 if (backing_store->IsDictionary()) {
8784 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); 8863 NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
8785 *capacity = dictionary->Capacity(); 8864 *capacity = dictionary->Capacity();
8786 *used = dictionary->NumberOfElements(); 8865 *used = dictionary->NumberOfElements();
8787 break; 8866 break;
8788 } 8867 }
8789 // Fall through. 8868 // Fall through.
8869 case FAST_SMI_ONLY_ELEMENTS:
8790 case FAST_ELEMENTS: 8870 case FAST_ELEMENTS:
8791 backing_store = FixedArray::cast(backing_store_base); 8871 backing_store = FixedArray::cast(backing_store_base);
8792 *capacity = backing_store->length(); 8872 *capacity = backing_store->length();
8793 for (int i = 0; i < *capacity; ++i) { 8873 for (int i = 0; i < *capacity; ++i) {
8794 if (!backing_store->get(i)->IsTheHole()) ++(*used); 8874 if (!backing_store->get(i)->IsTheHole()) ++(*used);
8795 } 8875 }
8796 break; 8876 break;
8797 case DICTIONARY_ELEMENTS: { 8877 case DICTIONARY_ELEMENTS: {
8798 NumberDictionary* dictionary = 8878 NumberDictionary* dictionary =
8799 NumberDictionary::cast(FixedArray::cast(elements())); 8879 NumberDictionary::cast(FixedArray::cast(elements()));
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
9055 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 9135 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
9056 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 9136 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
9057 return false; 9137 return false;
9058 } 9138 }
9059 } 9139 }
9060 9140
9061 // Handle [] on String objects. 9141 // Handle [] on String objects.
9062 if (this->IsStringObjectWithCharacterAt(index)) return true; 9142 if (this->IsStringObjectWithCharacterAt(index)) return true;
9063 9143
9064 switch (GetElementsKind()) { 9144 switch (GetElementsKind()) {
9145 case FAST_SMI_ONLY_ELEMENTS:
9065 case FAST_ELEMENTS: { 9146 case FAST_ELEMENTS: {
9066 uint32_t length = IsJSArray() ? 9147 uint32_t length = IsJSArray() ?
9067 static_cast<uint32_t>( 9148 static_cast<uint32_t>(
9068 Smi::cast(JSArray::cast(this)->length())->value()) : 9149 Smi::cast(JSArray::cast(this)->length())->value()) :
9069 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 9150 static_cast<uint32_t>(FixedArray::cast(elements())->length());
9070 return (index < length) && 9151 return (index < length) &&
9071 !FixedArray::cast(elements())->get(index)->IsTheHole(); 9152 !FixedArray::cast(elements())->get(index)->IsTheHole();
9072 } 9153 }
9073 case FAST_DOUBLE_ELEMENTS: { 9154 case FAST_DOUBLE_ELEMENTS: {
9074 uint32_t length = IsJSArray() ? 9155 uint32_t length = IsJSArray() ?
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
9294 } 9375 }
9295 // Compute the number of enumerable elements. 9376 // Compute the number of enumerable elements.
9296 return NumberOfLocalElements(static_cast<PropertyAttributes>(DONT_ENUM)); 9377 return NumberOfLocalElements(static_cast<PropertyAttributes>(DONT_ENUM));
9297 } 9378 }
9298 9379
9299 9380
9300 int JSObject::GetLocalElementKeys(FixedArray* storage, 9381 int JSObject::GetLocalElementKeys(FixedArray* storage,
9301 PropertyAttributes filter) { 9382 PropertyAttributes filter) {
9302 int counter = 0; 9383 int counter = 0;
9303 switch (GetElementsKind()) { 9384 switch (GetElementsKind()) {
9385 case FAST_SMI_ONLY_ELEMENTS:
9304 case FAST_ELEMENTS: { 9386 case FAST_ELEMENTS: {
9305 int length = IsJSArray() ? 9387 int length = IsJSArray() ?
9306 Smi::cast(JSArray::cast(this)->length())->value() : 9388 Smi::cast(JSArray::cast(this)->length())->value() :
9307 FixedArray::cast(elements())->length(); 9389 FixedArray::cast(elements())->length();
9308 for (int i = 0; i < length; i++) { 9390 for (int i = 0; i < length; i++) {
9309 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { 9391 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) {
9310 if (storage != NULL) { 9392 if (storage != NULL) {
9311 storage->set(counter, Smi::FromInt(i)); 9393 storage->set(counter, Smi::FromInt(i));
9312 } 9394 }
9313 counter++; 9395 counter++;
(...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after
10196 dict->CopyValuesTo(fast_elements); 10278 dict->CopyValuesTo(fast_elements);
10197 10279
10198 set_map(new_map); 10280 set_map(new_map);
10199 set_elements(fast_elements); 10281 set_elements(fast_elements);
10200 } else if (!HasFastDoubleElements()) { 10282 } else if (!HasFastDoubleElements()) {
10201 Object* obj; 10283 Object* obj;
10202 { MaybeObject* maybe_obj = EnsureWritableFastElements(); 10284 { MaybeObject* maybe_obj = EnsureWritableFastElements();
10203 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 10285 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
10204 } 10286 }
10205 } 10287 }
10206 ASSERT(HasFastElements() || HasFastDoubleElements()); 10288 ASSERT(HasFastTypeElements() ||
10289 HasFastDoubleElements());
10207 10290
10208 // Collect holes at the end, undefined before that and the rest at the 10291 // Collect holes at the end, undefined before that and the rest at the
10209 // start, and return the number of non-hole, non-undefined values. 10292 // start, and return the number of non-hole, non-undefined values.
10210 10293
10211 FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements()); 10294 FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements());
10212 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); 10295 uint32_t elements_length = static_cast<uint32_t>(elements_base->length());
10213 if (limit > elements_length) { 10296 if (limit > elements_length) {
10214 limit = elements_length ; 10297 limit = elements_length ;
10215 } 10298 }
10216 if (limit == 0) { 10299 if (limit == 0) {
(...skipping 1414 matching lines...) Expand 10 before | Expand all | Expand 10 after
11631 if (break_point_objects()->IsUndefined()) return 0; 11714 if (break_point_objects()->IsUndefined()) return 0;
11632 // Single break point. 11715 // Single break point.
11633 if (!break_point_objects()->IsFixedArray()) return 1; 11716 if (!break_point_objects()->IsFixedArray()) return 1;
11634 // Multiple break points. 11717 // Multiple break points.
11635 return FixedArray::cast(break_point_objects())->length(); 11718 return FixedArray::cast(break_point_objects())->length();
11636 } 11719 }
11637 #endif 11720 #endif
11638 11721
11639 11722
11640 } } // namespace v8::internal 11723 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698