OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 2308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2319 RETURN_IF_SCHEDULED_EXCEPTION(); | 2319 RETURN_IF_SCHEDULED_EXCEPTION(); |
2320 return raw_result; | 2320 return raw_result; |
2321 } | 2321 } |
2322 | 2322 |
2323 | 2323 |
2324 Object* JSObject::DeleteElementPostInterceptor(uint32_t index, | 2324 Object* JSObject::DeleteElementPostInterceptor(uint32_t index, |
2325 DeleteMode mode) { | 2325 DeleteMode mode) { |
2326 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); | 2326 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); |
2327 switch (GetElementsKind()) { | 2327 switch (GetElementsKind()) { |
2328 case FAST_ELEMENTS: { | 2328 case FAST_ELEMENTS: { |
| 2329 Object* obj = EnsureWritableFastElements(); |
| 2330 if (obj->IsFailure()) return obj; |
2329 uint32_t length = IsJSArray() ? | 2331 uint32_t length = IsJSArray() ? |
2330 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | 2332 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : |
2331 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 2333 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
2332 if (index < length) { | 2334 if (index < length) { |
2333 FixedArray::cast(elements())->set_the_hole(index); | 2335 FixedArray::cast(elements())->set_the_hole(index); |
2334 } | 2336 } |
2335 break; | 2337 break; |
2336 } | 2338 } |
2337 case DICTIONARY_ELEMENTS: { | 2339 case DICTIONARY_ELEMENTS: { |
2338 NumberDictionary* dictionary = element_dictionary(); | 2340 NumberDictionary* dictionary = element_dictionary(); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2399 if (HasIndexedInterceptor()) { | 2401 if (HasIndexedInterceptor()) { |
2400 // Skip interceptor if forcing deletion. | 2402 // Skip interceptor if forcing deletion. |
2401 if (mode == FORCE_DELETION) { | 2403 if (mode == FORCE_DELETION) { |
2402 return DeleteElementPostInterceptor(index, mode); | 2404 return DeleteElementPostInterceptor(index, mode); |
2403 } | 2405 } |
2404 return DeleteElementWithInterceptor(index); | 2406 return DeleteElementWithInterceptor(index); |
2405 } | 2407 } |
2406 | 2408 |
2407 switch (GetElementsKind()) { | 2409 switch (GetElementsKind()) { |
2408 case FAST_ELEMENTS: { | 2410 case FAST_ELEMENTS: { |
| 2411 Object* obj = EnsureWritableFastElements(); |
| 2412 if (obj->IsFailure()) return obj; |
2409 uint32_t length = IsJSArray() ? | 2413 uint32_t length = IsJSArray() ? |
2410 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | 2414 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : |
2411 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 2415 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
2412 if (index < length) { | 2416 if (index < length) { |
2413 FixedArray::cast(elements())->set_the_hole(index); | 2417 FixedArray::cast(elements())->set_the_hole(index); |
2414 } | 2418 } |
2415 break; | 2419 break; |
2416 } | 2420 } |
2417 case PIXEL_ELEMENTS: | 2421 case PIXEL_ELEMENTS: |
2418 case EXTERNAL_BYTE_ELEMENTS: | 2422 case EXTERNAL_BYTE_ELEMENTS: |
(...skipping 2571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4990 // Also drop the back pointer for that map transition, so that this | 4994 // Also drop the back pointer for that map transition, so that this |
4991 // map is not reached again by following a back pointer from a | 4995 // map is not reached again by following a back pointer from a |
4992 // non-live object. | 4996 // non-live object. |
4993 PropertyDetails details(Smi::cast(contents->get(i + 1))); | 4997 PropertyDetails details(Smi::cast(contents->get(i + 1))); |
4994 if (details.type() == MAP_TRANSITION || | 4998 if (details.type() == MAP_TRANSITION || |
4995 details.type() == CONSTANT_TRANSITION) { | 4999 details.type() == CONSTANT_TRANSITION) { |
4996 Map* target = reinterpret_cast<Map*>(contents->get(i)); | 5000 Map* target = reinterpret_cast<Map*>(contents->get(i)); |
4997 ASSERT(target->IsHeapObject()); | 5001 ASSERT(target->IsHeapObject()); |
4998 if (!target->IsMarked()) { | 5002 if (!target->IsMarked()) { |
4999 ASSERT(target->IsMap()); | 5003 ASSERT(target->IsMap()); |
5000 contents->set(i + 1, NullDescriptorDetails); | 5004 contents->set_unchecked(i + 1, NullDescriptorDetails); |
5001 contents->set_null(i); | 5005 contents->set_null_unchecked(i); |
5002 ASSERT(target->prototype() == this || | 5006 ASSERT(target->prototype() == this || |
5003 target->prototype() == real_prototype); | 5007 target->prototype() == real_prototype); |
5004 // Getter prototype() is read-only, set_prototype() has side effects. | 5008 // Getter prototype() is read-only, set_prototype() has side effects. |
5005 *RawField(target, Map::kPrototypeOffset) = real_prototype; | 5009 *RawField(target, Map::kPrototypeOffset) = real_prototype; |
5006 } | 5010 } |
5007 } | 5011 } |
5008 } | 5012 } |
5009 } | 5013 } |
5010 | 5014 |
5011 | 5015 |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5572 | 5576 |
5573 Object* smi_length = len->ToSmi(); | 5577 Object* smi_length = len->ToSmi(); |
5574 if (smi_length->IsSmi()) { | 5578 if (smi_length->IsSmi()) { |
5575 const int value = Smi::cast(smi_length)->value(); | 5579 const int value = Smi::cast(smi_length)->value(); |
5576 if (value < 0) return ArrayLengthRangeError(); | 5580 if (value < 0) return ArrayLengthRangeError(); |
5577 switch (GetElementsKind()) { | 5581 switch (GetElementsKind()) { |
5578 case FAST_ELEMENTS: { | 5582 case FAST_ELEMENTS: { |
5579 int old_capacity = FixedArray::cast(elements())->length(); | 5583 int old_capacity = FixedArray::cast(elements())->length(); |
5580 if (value <= old_capacity) { | 5584 if (value <= old_capacity) { |
5581 if (IsJSArray()) { | 5585 if (IsJSArray()) { |
| 5586 Object* obj = EnsureWritableFastElements(); |
| 5587 if (obj->IsFailure()) return obj; |
5582 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); | 5588 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); |
5583 // NOTE: We may be able to optimize this by removing the | 5589 // NOTE: We may be able to optimize this by removing the |
5584 // last part of the elements backing storage array and | 5590 // last part of the elements backing storage array and |
5585 // setting the capacity to the new size. | 5591 // setting the capacity to the new size. |
5586 for (int i = value; i < old_length; i++) { | 5592 for (int i = value; i < old_length; i++) { |
5587 FixedArray::cast(elements())->set_the_hole(i); | 5593 FixedArray::cast(elements())->set_the_hole(i); |
5588 } | 5594 } |
5589 JSArray::cast(this)->set_length(Smi::cast(smi_length)); | 5595 JSArray::cast(this)->set_length(Smi::cast(smi_length)); |
5590 } | 5596 } |
5591 return this; | 5597 return this; |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6037 return NULL; | 6043 return NULL; |
6038 } | 6044 } |
6039 | 6045 |
6040 | 6046 |
6041 // Adding n elements in fast case is O(n*n). | 6047 // Adding n elements in fast case is O(n*n). |
6042 // Note: revisit design to have dual undefined values to capture absent | 6048 // Note: revisit design to have dual undefined values to capture absent |
6043 // elements. | 6049 // elements. |
6044 Object* JSObject::SetFastElement(uint32_t index, Object* value) { | 6050 Object* JSObject::SetFastElement(uint32_t index, Object* value) { |
6045 ASSERT(HasFastElements()); | 6051 ASSERT(HasFastElements()); |
6046 | 6052 |
6047 FixedArray* elms = FixedArray::cast(elements()); | 6053 Object* elms_obj = EnsureWritableFastElements(); |
| 6054 if (elms_obj->IsFailure()) return elms_obj; |
| 6055 FixedArray* elms = FixedArray::cast(elms_obj); |
6048 uint32_t elms_length = static_cast<uint32_t>(elms->length()); | 6056 uint32_t elms_length = static_cast<uint32_t>(elms->length()); |
6049 | 6057 |
6050 if (!IsJSArray() && (index >= elms_length || elms->get(index)->IsTheHole())) { | 6058 if (!IsJSArray() && (index >= elms_length || elms->get(index)->IsTheHole())) { |
6051 if (SetElementWithCallbackSetterInPrototypes(index, value)) { | 6059 if (SetElementWithCallbackSetterInPrototypes(index, value)) { |
6052 return value; | 6060 return value; |
6053 } | 6061 } |
6054 } | 6062 } |
6055 | 6063 |
6056 // Check whether there is extra space in fixed array.. | 6064 // Check whether there is extra space in fixed array.. |
6057 if (index < elms_length) { | 6065 if (index < elms_length) { |
(...skipping 23 matching lines...) Expand all Loading... |
6081 } | 6089 } |
6082 } | 6090 } |
6083 | 6091 |
6084 // Otherwise default to slow case. | 6092 // Otherwise default to slow case. |
6085 Object* obj = NormalizeElements(); | 6093 Object* obj = NormalizeElements(); |
6086 if (obj->IsFailure()) return obj; | 6094 if (obj->IsFailure()) return obj; |
6087 ASSERT(HasDictionaryElements()); | 6095 ASSERT(HasDictionaryElements()); |
6088 return SetElement(index, value); | 6096 return SetElement(index, value); |
6089 } | 6097 } |
6090 | 6098 |
| 6099 |
6091 Object* JSObject::SetElement(uint32_t index, Object* value) { | 6100 Object* JSObject::SetElement(uint32_t index, Object* value) { |
6092 // Check access rights if needed. | 6101 // Check access rights if needed. |
6093 if (IsAccessCheckNeeded() && | 6102 if (IsAccessCheckNeeded() && |
6094 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 6103 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
6095 HandleScope scope; | 6104 HandleScope scope; |
6096 Handle<Object> value_handle(value); | 6105 Handle<Object> value_handle(value); |
6097 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 6106 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); |
6098 return *value_handle; | 6107 return *value_handle; |
6099 } | 6108 } |
6100 | 6109 |
(...skipping 1458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7559 | 7568 |
7560 PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED: TENURED; | 7569 PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED: TENURED; |
7561 Object* new_array = | 7570 Object* new_array = |
7562 Heap::AllocateFixedArray(dict->NumberOfElements(), tenure); | 7571 Heap::AllocateFixedArray(dict->NumberOfElements(), tenure); |
7563 if (new_array->IsFailure()) return new_array; | 7572 if (new_array->IsFailure()) return new_array; |
7564 FixedArray* fast_elements = FixedArray::cast(new_array); | 7573 FixedArray* fast_elements = FixedArray::cast(new_array); |
7565 dict->CopyValuesTo(fast_elements); | 7574 dict->CopyValuesTo(fast_elements); |
7566 | 7575 |
7567 set_map(new_map); | 7576 set_map(new_map); |
7568 set_elements(fast_elements); | 7577 set_elements(fast_elements); |
| 7578 } else { |
| 7579 Object* obj = EnsureWritableFastElements(); |
| 7580 if (obj->IsFailure()) return obj; |
7569 } | 7581 } |
7570 ASSERT(HasFastElements()); | 7582 ASSERT(HasFastElements()); |
7571 | 7583 |
7572 // Collect holes at the end, undefined before that and the rest at the | 7584 // Collect holes at the end, undefined before that and the rest at the |
7573 // start, and return the number of non-hole, non-undefined values. | 7585 // start, and return the number of non-hole, non-undefined values. |
7574 | 7586 |
7575 FixedArray* elements = FixedArray::cast(this->elements()); | 7587 FixedArray* elements = FixedArray::cast(this->elements()); |
7576 uint32_t elements_length = static_cast<uint32_t>(elements->length()); | 7588 uint32_t elements_length = static_cast<uint32_t>(elements->length()); |
7577 if (limit > elements_length) { | 7589 if (limit > elements_length) { |
7578 limit = elements_length ; | 7590 limit = elements_length ; |
(...skipping 1175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8754 if (break_point_objects()->IsUndefined()) return 0; | 8766 if (break_point_objects()->IsUndefined()) return 0; |
8755 // Single beak point. | 8767 // Single beak point. |
8756 if (!break_point_objects()->IsFixedArray()) return 1; | 8768 if (!break_point_objects()->IsFixedArray()) return 1; |
8757 // Multiple break points. | 8769 // Multiple break points. |
8758 return FixedArray::cast(break_point_objects())->length(); | 8770 return FixedArray::cast(break_point_objects())->length(); |
8759 } | 8771 } |
8760 #endif | 8772 #endif |
8761 | 8773 |
8762 | 8774 |
8763 } } // namespace v8::internal | 8775 } } // namespace v8::internal |
OLD | NEW |