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

Side by Side Diff: src/objects.cc

Issue 2144006: Cardmarking writebarrier. (Closed)
Patch Set: change NewSpace and SemiSpace Contains to match HasHeapObjectTag Created 10 years, 7 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
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 4766 matching lines...) Expand 10 before | Expand all | Expand 10 after
4777 for (; i < length; i++) { 4777 for (; i < length; i++) {
4778 hasher.AddCharacterNoIndex(chars[i]); 4778 hasher.AddCharacterNoIndex(chars[i]);
4779 } 4779 }
4780 } 4780 }
4781 return hasher.GetHashField(); 4781 return hasher.GetHashField();
4782 } 4782 }
4783 4783
4784 4784
4785 uint32_t String::ComputeAndSetHash() { 4785 uint32_t String::ComputeAndSetHash() {
4786 // Should only be called if hash code has not yet been computed. 4786 // Should only be called if hash code has not yet been computed.
4787 ASSERT(!(hash_field() & kHashComputedMask)); 4787 ASSERT(!HasHashCode());
4788 4788
4789 const int len = length(); 4789 const int len = length();
4790 4790
4791 // Compute the hash code. 4791 // Compute the hash code.
4792 uint32_t field = 0; 4792 uint32_t field = 0;
4793 if (StringShape(this).IsSequentialAscii()) { 4793 if (StringShape(this).IsSequentialAscii()) {
4794 field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), len); 4794 field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), len);
4795 } else if (StringShape(this).IsSequentialTwoByte()) { 4795 } else if (StringShape(this).IsSequentialTwoByte()) {
4796 field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(), len); 4796 field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(), len);
4797 } else { 4797 } else {
4798 StringInputBuffer buffer(this); 4798 StringInputBuffer buffer(this);
4799 field = ComputeHashField(&buffer, len); 4799 field = ComputeHashField(&buffer, len);
4800 } 4800 }
4801 4801
4802 // Store the hash code in the object. 4802 // Store the hash code in the object.
4803 set_hash_field(field); 4803 set_hash_field(field);
4804 4804
4805 // Check the hash code is there. 4805 // Check the hash code is there.
4806 ASSERT(hash_field() & kHashComputedMask); 4806 ASSERT(HasHashCode());
4807 uint32_t result = field >> kHashShift; 4807 uint32_t result = field >> kHashShift;
4808 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. 4808 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed.
4809 return result; 4809 return result;
4810 } 4810 }
4811 4811
4812 4812
4813 bool String::ComputeArrayIndex(unibrow::CharacterStream* buffer, 4813 bool String::ComputeArrayIndex(unibrow::CharacterStream* buffer,
4814 uint32_t* index, 4814 uint32_t* index,
4815 int length) { 4815 int length) {
4816 if (length == 0 || length > kMaxArrayIndexSize) return false; 4816 if (length == 0 || length > kMaxArrayIndexSize) return false;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4851 } else { 4851 } else {
4852 StringInputBuffer buffer(this); 4852 StringInputBuffer buffer(this);
4853 return ComputeArrayIndex(&buffer, index, length()); 4853 return ComputeArrayIndex(&buffer, index, length());
4854 } 4854 }
4855 } 4855 }
4856 4856
4857 4857
4858 static inline uint32_t HashField(uint32_t hash, 4858 static inline uint32_t HashField(uint32_t hash,
4859 bool is_array_index, 4859 bool is_array_index,
4860 int length = -1) { 4860 int length = -1) {
4861 uint32_t result = 4861 uint32_t result = (hash << String::kHashShift);
4862 (hash << String::kHashShift) | String::kHashComputedMask;
4863 if (is_array_index) { 4862 if (is_array_index) {
4864 // For array indexes mix the length into the hash as an array index could 4863 // For array indexes mix the length into the hash as an array index could
4865 // be zero. 4864 // be zero.
4866 ASSERT(length > 0); 4865 ASSERT(length > 0);
4867 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 4866 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
4868 (1 << String::kArrayIndexValueBits)); 4867 (1 << String::kArrayIndexValueBits));
4869 result |= String::kIsArrayIndexMask; 4868 result |= String::kIsArrayIndexMask;
4870 result |= length << String::kArrayIndexHashLengthShift; 4869 result |= length << String::kArrayIndexHashLengthShift;
4871 } 4870 }
4872 return result; 4871 return result;
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after
5647 } 5646 }
5648 default: 5647 default:
5649 UNREACHABLE(); 5648 UNREACHABLE();
5650 break; 5649 break;
5651 } 5650 }
5652 } 5651 }
5653 5652
5654 // General slow case. 5653 // General slow case.
5655 if (len->IsNumber()) { 5654 if (len->IsNumber()) {
5656 uint32_t length; 5655 uint32_t length;
5657 if (Array::IndexFromObject(len, &length)) { 5656 if (len->ToArrayIndex(&length)) {
5658 return SetSlowElements(len); 5657 return SetSlowElements(len);
5659 } else { 5658 } else {
5660 return ArrayLengthRangeError(); 5659 return ArrayLengthRangeError();
5661 } 5660 }
5662 } 5661 }
5663 5662
5664 // len is not a number so make the array size one and 5663 // len is not a number so make the array size one and
5665 // set only element to len. 5664 // set only element to len.
5666 Object* obj = Heap::AllocateFixedArray(1); 5665 Object* obj = Heap::AllocateFixedArray(1);
5667 if (obj->IsFailure()) return obj; 5666 if (obj->IsFailure()) return obj;
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
6071 return value; 6070 return value;
6072 } 6071 }
6073 } 6072 }
6074 6073
6075 // Check whether there is extra space in fixed array.. 6074 // Check whether there is extra space in fixed array..
6076 if (index < elms_length) { 6075 if (index < elms_length) {
6077 elms->set(index, value); 6076 elms->set(index, value);
6078 if (IsJSArray()) { 6077 if (IsJSArray()) {
6079 // Update the length of the array if needed. 6078 // Update the length of the array if needed.
6080 uint32_t array_length = 0; 6079 uint32_t array_length = 0;
6081 CHECK(Array::IndexFromObject(JSArray::cast(this)->length(), 6080 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length));
6082 &array_length));
6083 if (index >= array_length) { 6081 if (index >= array_length) {
6084 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); 6082 JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
6085 } 6083 }
6086 } 6084 }
6087 return value; 6085 return value;
6088 } 6086 }
6089 6087
6090 // Allow gap in fast case. 6088 // Allow gap in fast case.
6091 if ((index - elms_length) < kMaxGap) { 6089 if ((index - elms_length) < kMaxGap) {
6092 // Try allocating extra space. 6090 // Try allocating extra space.
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
6210 JSArray* array = JSArray::cast(this); 6208 JSArray* array = JSArray::cast(this);
6211 Object* return_value = array->JSArrayUpdateLengthFromIndex(index, 6209 Object* return_value = array->JSArrayUpdateLengthFromIndex(index,
6212 value); 6210 value);
6213 if (return_value->IsFailure()) return return_value; 6211 if (return_value->IsFailure()) return return_value;
6214 } 6212 }
6215 6213
6216 // Attempt to put this object back in fast case. 6214 // Attempt to put this object back in fast case.
6217 if (ShouldConvertToFastElements()) { 6215 if (ShouldConvertToFastElements()) {
6218 uint32_t new_length = 0; 6216 uint32_t new_length = 0;
6219 if (IsJSArray()) { 6217 if (IsJSArray()) {
6220 CHECK(Array::IndexFromObject(JSArray::cast(this)->length(), 6218 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length));
6221 &new_length));
6222 JSArray::cast(this)->set_length(Smi::FromInt(new_length)); 6219 JSArray::cast(this)->set_length(Smi::FromInt(new_length));
6223 } else { 6220 } else {
6224 new_length = NumberDictionary::cast(elements())->max_number_key() + 1; 6221 new_length = NumberDictionary::cast(elements())->max_number_key() + 1;
6225 } 6222 }
6226 Object* obj = Heap::AllocateFixedArrayWithHoles(new_length); 6223 Object* obj = Heap::AllocateFixedArrayWithHoles(new_length);
6227 if (obj->IsFailure()) return obj; 6224 if (obj->IsFailure()) return obj;
6228 SetFastElements(FixedArray::cast(obj)); 6225 SetFastElements(FixedArray::cast(obj));
6229 #ifdef DEBUG 6226 #ifdef DEBUG
6230 if (FLAG_trace_normalization) { 6227 if (FLAG_trace_normalization) {
6231 PrintF("Object elements are fast case again:\n"); 6228 PrintF("Object elements are fast case again:\n");
(...skipping 10 matching lines...) Expand all
6242 } 6239 }
6243 // All possible cases have been handled above. Add a return to avoid the 6240 // All possible cases have been handled above. Add a return to avoid the
6244 // complaints from the compiler. 6241 // complaints from the compiler.
6245 UNREACHABLE(); 6242 UNREACHABLE();
6246 return Heap::null_value(); 6243 return Heap::null_value();
6247 } 6244 }
6248 6245
6249 6246
6250 Object* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, Object* value) { 6247 Object* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, Object* value) {
6251 uint32_t old_len = 0; 6248 uint32_t old_len = 0;
6252 CHECK(Array::IndexFromObject(length(), &old_len)); 6249 CHECK(length()->ToArrayIndex(&old_len));
6253 // Check to see if we need to update the length. For now, we make 6250 // Check to see if we need to update the length. For now, we make
6254 // sure that the length stays within 32-bits (unsigned). 6251 // sure that the length stays within 32-bits (unsigned).
6255 if (index >= old_len && index != 0xffffffff) { 6252 if (index >= old_len && index != 0xffffffff) {
6256 Object* len = 6253 Object* len =
6257 Heap::NumberFromDouble(static_cast<double>(index) + 1); 6254 Heap::NumberFromDouble(static_cast<double>(index) + 1);
6258 if (len->IsFailure()) return len; 6255 if (len->IsFailure()) return len;
6259 set_length(len); 6256 set_length(len);
6260 } 6257 }
6261 return value; 6258 return value;
6262 } 6259 }
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
6524 // dictionary, we cannot go back to fast case. 6521 // dictionary, we cannot go back to fast case.
6525 if (dictionary->requires_slow_elements()) return false; 6522 if (dictionary->requires_slow_elements()) return false;
6526 // An object requiring access checks is never allowed to have fast 6523 // An object requiring access checks is never allowed to have fast
6527 // elements. If it had fast elements we would skip security checks. 6524 // elements. If it had fast elements we would skip security checks.
6528 if (IsAccessCheckNeeded()) return false; 6525 if (IsAccessCheckNeeded()) return false;
6529 // If the dictionary backing storage takes up roughly half as much 6526 // If the dictionary backing storage takes up roughly half as much
6530 // space as a fast-case backing storage would the array should have 6527 // space as a fast-case backing storage would the array should have
6531 // fast elements. 6528 // fast elements.
6532 uint32_t length = 0; 6529 uint32_t length = 0;
6533 if (IsJSArray()) { 6530 if (IsJSArray()) {
6534 CHECK(Array::IndexFromObject(JSArray::cast(this)->length(), &length)); 6531 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length));
6535 } else { 6532 } else {
6536 length = dictionary->max_number_key(); 6533 length = dictionary->max_number_key();
6537 } 6534 }
6538 return static_cast<uint32_t>(dictionary->Capacity()) >= 6535 return static_cast<uint32_t>(dictionary->Capacity()) >=
6539 (length / (2 * NumberDictionary::kEntrySize)); 6536 (length / (2 * NumberDictionary::kEntrySize));
6540 } 6537 }
6541 6538
6542 6539
6543 // Certain compilers request function template instantiation when they 6540 // Certain compilers request function template instantiation when they
6544 // see the definition of the other template functions in the 6541 // see the definition of the other template functions in the
(...skipping 2181 matching lines...) Expand 10 before | Expand all | Expand 10 after
8726 if (break_point_objects()->IsUndefined()) return 0; 8723 if (break_point_objects()->IsUndefined()) return 0;
8727 // Single beak point. 8724 // Single beak point.
8728 if (!break_point_objects()->IsFixedArray()) return 1; 8725 if (!break_point_objects()->IsFixedArray()) return 1;
8729 // Multiple break points. 8726 // Multiple break points.
8730 return FixedArray::cast(break_point_objects())->length(); 8727 return FixedArray::cast(break_point_objects())->length();
8731 } 8728 }
8732 #endif 8729 #endif
8733 8730
8734 8731
8735 } } // namespace v8::internal 8732 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | src/spaces.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698