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

Side by Side Diff: src/objects.cc

Issue 3144002: Copy-on-write arrays. (Closed)
Patch Set: Review fixes. Created 10 years, 4 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
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698