| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <sstream> | 5 #include <sstream> |
| 6 | 6 |
| 7 #include "src/v8.h" | 7 #include "src/v8.h" |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
| (...skipping 1165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1176 if (len > kMaxShortPrintLength) { | 1176 if (len > kMaxShortPrintLength) { |
| 1177 accumulator->Add("<Very long string[%u]>", len); | 1177 accumulator->Add("<Very long string[%u]>", len); |
| 1178 return; | 1178 return; |
| 1179 } | 1179 } |
| 1180 | 1180 |
| 1181 if (!LooksValid()) { | 1181 if (!LooksValid()) { |
| 1182 accumulator->Add("<Invalid String>"); | 1182 accumulator->Add("<Invalid String>"); |
| 1183 return; | 1183 return; |
| 1184 } | 1184 } |
| 1185 | 1185 |
| 1186 ConsStringIteratorOp op; | 1186 StringCharacterStream stream(this); |
| 1187 StringCharacterStream stream(this, &op); | |
| 1188 | 1187 |
| 1189 bool truncated = false; | 1188 bool truncated = false; |
| 1190 if (len > kMaxShortPrintLength) { | 1189 if (len > kMaxShortPrintLength) { |
| 1191 len = kMaxShortPrintLength; | 1190 len = kMaxShortPrintLength; |
| 1192 truncated = true; | 1191 truncated = true; |
| 1193 } | 1192 } |
| 1194 bool one_byte = true; | 1193 bool one_byte = true; |
| 1195 for (int i = 0; i < len; i++) { | 1194 for (int i = 0; i < len; i++) { |
| 1196 uint16_t c = stream.GetNext(); | 1195 uint16_t c = stream.GetNext(); |
| 1197 | 1196 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1230 accumulator->Put('.'); | 1229 accumulator->Put('.'); |
| 1231 } | 1230 } |
| 1232 accumulator->Put('>'); | 1231 accumulator->Put('>'); |
| 1233 } | 1232 } |
| 1234 return; | 1233 return; |
| 1235 } | 1234 } |
| 1236 | 1235 |
| 1237 | 1236 |
| 1238 void String::PrintUC16(std::ostream& os, int start, int end) { // NOLINT | 1237 void String::PrintUC16(std::ostream& os, int start, int end) { // NOLINT |
| 1239 if (end < 0) end = length(); | 1238 if (end < 0) end = length(); |
| 1240 ConsStringIteratorOp op; | 1239 StringCharacterStream stream(this, start); |
| 1241 StringCharacterStream stream(this, &op, start); | |
| 1242 for (int i = start; i < end && stream.HasMore(); i++) { | 1240 for (int i = start; i < end && stream.HasMore(); i++) { |
| 1243 os << AsUC16(stream.GetNext()); | 1241 os << AsUC16(stream.GetNext()); |
| 1244 } | 1242 } |
| 1245 } | 1243 } |
| 1246 | 1244 |
| 1247 | 1245 |
| 1248 void JSObject::JSObjectShortPrint(StringStream* accumulator) { | 1246 void JSObject::JSObjectShortPrint(StringStream* accumulator) { |
| 1249 switch (map()->instance_type()) { | 1247 switch (map()->instance_type()) { |
| 1250 case JS_ARRAY_TYPE: { | 1248 case JS_ARRAY_TYPE: { |
| 1251 double length = JSArray::cast(this)->length()->IsUndefined() | 1249 double length = JSArray::cast(this)->length()->IsUndefined() |
| (...skipping 6846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8098 | 8096 |
| 8099 | 8097 |
| 8100 SmartArrayPointer<char> String::ToCString(AllowNullsFlag allow_nulls, | 8098 SmartArrayPointer<char> String::ToCString(AllowNullsFlag allow_nulls, |
| 8101 RobustnessFlag robust_flag, | 8099 RobustnessFlag robust_flag, |
| 8102 int offset, | 8100 int offset, |
| 8103 int length, | 8101 int length, |
| 8104 int* length_return) { | 8102 int* length_return) { |
| 8105 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { | 8103 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { |
| 8106 return SmartArrayPointer<char>(NULL); | 8104 return SmartArrayPointer<char>(NULL); |
| 8107 } | 8105 } |
| 8108 Heap* heap = GetHeap(); | |
| 8109 | |
| 8110 // Negative length means the to the end of the string. | 8106 // Negative length means the to the end of the string. |
| 8111 if (length < 0) length = kMaxInt - offset; | 8107 if (length < 0) length = kMaxInt - offset; |
| 8112 | 8108 |
| 8113 // Compute the size of the UTF-8 string. Start at the specified offset. | 8109 // Compute the size of the UTF-8 string. Start at the specified offset. |
| 8114 Access<ConsStringIteratorOp> op( | 8110 StringCharacterStream stream(this, offset); |
| 8115 heap->isolate()->objects_string_iterator()); | |
| 8116 StringCharacterStream stream(this, op.value(), offset); | |
| 8117 int character_position = offset; | 8111 int character_position = offset; |
| 8118 int utf8_bytes = 0; | 8112 int utf8_bytes = 0; |
| 8119 int last = unibrow::Utf16::kNoPreviousCharacter; | 8113 int last = unibrow::Utf16::kNoPreviousCharacter; |
| 8120 while (stream.HasMore() && character_position++ < offset + length) { | 8114 while (stream.HasMore() && character_position++ < offset + length) { |
| 8121 uint16_t character = stream.GetNext(); | 8115 uint16_t character = stream.GetNext(); |
| 8122 utf8_bytes += unibrow::Utf8::Length(character, last); | 8116 utf8_bytes += unibrow::Utf8::Length(character, last); |
| 8123 last = character; | 8117 last = character; |
| 8124 } | 8118 } |
| 8125 | 8119 |
| 8126 if (length_return) { | 8120 if (length_return) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8173 } | 8167 } |
| 8174 UNREACHABLE(); | 8168 UNREACHABLE(); |
| 8175 return NULL; | 8169 return NULL; |
| 8176 } | 8170 } |
| 8177 | 8171 |
| 8178 | 8172 |
| 8179 SmartArrayPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { | 8173 SmartArrayPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { |
| 8180 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { | 8174 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { |
| 8181 return SmartArrayPointer<uc16>(); | 8175 return SmartArrayPointer<uc16>(); |
| 8182 } | 8176 } |
| 8183 Heap* heap = GetHeap(); | 8177 StringCharacterStream stream(this); |
| 8184 | |
| 8185 Access<ConsStringIteratorOp> op( | |
| 8186 heap->isolate()->objects_string_iterator()); | |
| 8187 StringCharacterStream stream(this, op.value()); | |
| 8188 | 8178 |
| 8189 uc16* result = NewArray<uc16>(length() + 1); | 8179 uc16* result = NewArray<uc16>(length() + 1); |
| 8190 | 8180 |
| 8191 int i = 0; | 8181 int i = 0; |
| 8192 while (stream.HasMore()) { | 8182 while (stream.HasMore()) { |
| 8193 uint16_t character = stream.GetNext(); | 8183 uint16_t character = stream.GetNext(); |
| 8194 result[i++] = character; | 8184 result[i++] = character; |
| 8195 } | 8185 } |
| 8196 result[i] = 0; | 8186 result[i] = 0; |
| 8197 return SmartArrayPointer<uc16>(result); | 8187 return SmartArrayPointer<uc16>(result); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8281 DCHECK(content.IsFlat()); | 8271 DCHECK(content.IsFlat()); |
| 8282 is_one_byte_ = content.IsOneByte(); | 8272 is_one_byte_ = content.IsOneByte(); |
| 8283 if (is_one_byte_) { | 8273 if (is_one_byte_) { |
| 8284 start_ = content.ToOneByteVector().start(); | 8274 start_ = content.ToOneByteVector().start(); |
| 8285 } else { | 8275 } else { |
| 8286 start_ = content.ToUC16Vector().start(); | 8276 start_ = content.ToUC16Vector().start(); |
| 8287 } | 8277 } |
| 8288 } | 8278 } |
| 8289 | 8279 |
| 8290 | 8280 |
| 8291 void ConsStringIteratorOp::Initialize(ConsString* cons_string, int offset) { | 8281 void ConsStringIterator::Initialize(ConsString* cons_string, int offset) { |
| 8292 DCHECK(cons_string != NULL); | 8282 DCHECK(cons_string != NULL); |
| 8293 root_ = cons_string; | 8283 root_ = cons_string; |
| 8294 consumed_ = offset; | 8284 consumed_ = offset; |
| 8295 // Force stack blown condition to trigger restart. | 8285 // Force stack blown condition to trigger restart. |
| 8296 depth_ = 1; | 8286 depth_ = 1; |
| 8297 maximum_depth_ = kStackSize + depth_; | 8287 maximum_depth_ = kStackSize + depth_; |
| 8298 DCHECK(StackBlown()); | 8288 DCHECK(StackBlown()); |
| 8299 } | 8289 } |
| 8300 | 8290 |
| 8301 | 8291 |
| 8302 String* ConsStringIteratorOp::Continue(int* offset_out) { | 8292 String* ConsStringIterator::Continue(int* offset_out) { |
| 8303 DCHECK(depth_ != 0); | 8293 DCHECK(depth_ != 0); |
| 8304 DCHECK_EQ(0, *offset_out); | 8294 DCHECK_EQ(0, *offset_out); |
| 8305 bool blew_stack = StackBlown(); | 8295 bool blew_stack = StackBlown(); |
| 8306 String* string = NULL; | 8296 String* string = NULL; |
| 8307 // Get the next leaf if there is one. | 8297 // Get the next leaf if there is one. |
| 8308 if (!blew_stack) string = NextLeaf(&blew_stack); | 8298 if (!blew_stack) string = NextLeaf(&blew_stack); |
| 8309 // Restart search from root. | 8299 // Restart search from root. |
| 8310 if (blew_stack) { | 8300 if (blew_stack) { |
| 8311 DCHECK(string == NULL); | 8301 DCHECK(string == NULL); |
| 8312 string = Search(offset_out); | 8302 string = Search(offset_out); |
| 8313 } | 8303 } |
| 8314 // Ensure future calls return null immediately. | 8304 // Ensure future calls return null immediately. |
| 8315 if (string == NULL) Reset(NULL); | 8305 if (string == NULL) Reset(NULL); |
| 8316 return string; | 8306 return string; |
| 8317 } | 8307 } |
| 8318 | 8308 |
| 8319 | 8309 |
| 8320 String* ConsStringIteratorOp::Search(int* offset_out) { | 8310 String* ConsStringIterator::Search(int* offset_out) { |
| 8321 ConsString* cons_string = root_; | 8311 ConsString* cons_string = root_; |
| 8322 // Reset the stack, pushing the root string. | 8312 // Reset the stack, pushing the root string. |
| 8323 depth_ = 1; | 8313 depth_ = 1; |
| 8324 maximum_depth_ = 1; | 8314 maximum_depth_ = 1; |
| 8325 frames_[0] = cons_string; | 8315 frames_[0] = cons_string; |
| 8326 const int consumed = consumed_; | 8316 const int consumed = consumed_; |
| 8327 int offset = 0; | 8317 int offset = 0; |
| 8328 while (true) { | 8318 while (true) { |
| 8329 // Loop until the string is found which contains the target offset. | 8319 // Loop until the string is found which contains the target offset. |
| 8330 String* string = cons_string->first(); | 8320 String* string = cons_string->first(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8371 // Adjust return values and exit. | 8361 // Adjust return values and exit. |
| 8372 consumed_ = offset + length; | 8362 consumed_ = offset + length; |
| 8373 *offset_out = consumed - offset; | 8363 *offset_out = consumed - offset; |
| 8374 return string; | 8364 return string; |
| 8375 } | 8365 } |
| 8376 UNREACHABLE(); | 8366 UNREACHABLE(); |
| 8377 return NULL; | 8367 return NULL; |
| 8378 } | 8368 } |
| 8379 | 8369 |
| 8380 | 8370 |
| 8381 String* ConsStringIteratorOp::NextLeaf(bool* blew_stack) { | 8371 String* ConsStringIterator::NextLeaf(bool* blew_stack) { |
| 8382 while (true) { | 8372 while (true) { |
| 8383 // Tree traversal complete. | 8373 // Tree traversal complete. |
| 8384 if (depth_ == 0) { | 8374 if (depth_ == 0) { |
| 8385 *blew_stack = false; | 8375 *blew_stack = false; |
| 8386 return NULL; | 8376 return NULL; |
| 8387 } | 8377 } |
| 8388 // We've lost track of higher nodes. | 8378 // We've lost track of higher nodes. |
| 8389 if (StackBlown()) { | 8379 if (StackBlown()) { |
| 8390 *blew_stack = true; | 8380 *blew_stack = true; |
| 8391 return NULL; | 8381 return NULL; |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8648 public: | 8638 public: |
| 8649 static inline bool compare(const uint8_t* a, const uint8_t* b, int len) { | 8639 static inline bool compare(const uint8_t* a, const uint8_t* b, int len) { |
| 8650 return CompareRawStringContents(a, b, len); | 8640 return CompareRawStringContents(a, b, len); |
| 8651 } | 8641 } |
| 8652 }; | 8642 }; |
| 8653 | 8643 |
| 8654 | 8644 |
| 8655 class StringComparator { | 8645 class StringComparator { |
| 8656 class State { | 8646 class State { |
| 8657 public: | 8647 public: |
| 8658 explicit inline State(ConsStringIteratorOp* op) | 8648 State() : is_one_byte_(true), length_(0), buffer8_(NULL) {} |
| 8659 : op_(op), is_one_byte_(true), length_(0), buffer8_(NULL) {} | |
| 8660 | 8649 |
| 8661 inline void Init(String* string) { | 8650 void Init(String* string) { |
| 8662 ConsString* cons_string = String::VisitFlat(this, string); | 8651 ConsString* cons_string = String::VisitFlat(this, string); |
| 8663 op_->Reset(cons_string); | 8652 iter_.Reset(cons_string); |
| 8664 if (cons_string != NULL) { | 8653 if (cons_string != NULL) { |
| 8665 int offset; | 8654 int offset; |
| 8666 string = op_->Next(&offset); | 8655 string = iter_.Next(&offset); |
| 8667 String::VisitFlat(this, string, offset); | 8656 String::VisitFlat(this, string, offset); |
| 8668 } | 8657 } |
| 8669 } | 8658 } |
| 8670 | 8659 |
| 8671 inline void VisitOneByteString(const uint8_t* chars, int length) { | 8660 inline void VisitOneByteString(const uint8_t* chars, int length) { |
| 8672 is_one_byte_ = true; | 8661 is_one_byte_ = true; |
| 8673 buffer8_ = chars; | 8662 buffer8_ = chars; |
| 8674 length_ = length; | 8663 length_ = length; |
| 8675 } | 8664 } |
| 8676 | 8665 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 8687 if (is_one_byte_) { | 8676 if (is_one_byte_) { |
| 8688 buffer8_ += consumed; | 8677 buffer8_ += consumed; |
| 8689 } else { | 8678 } else { |
| 8690 buffer16_ += consumed; | 8679 buffer16_ += consumed; |
| 8691 } | 8680 } |
| 8692 length_ -= consumed; | 8681 length_ -= consumed; |
| 8693 return; | 8682 return; |
| 8694 } | 8683 } |
| 8695 // Advance state. | 8684 // Advance state. |
| 8696 int offset; | 8685 int offset; |
| 8697 String* next = op_->Next(&offset); | 8686 String* next = iter_.Next(&offset); |
| 8698 DCHECK_EQ(0, offset); | 8687 DCHECK_EQ(0, offset); |
| 8699 DCHECK(next != NULL); | 8688 DCHECK(next != NULL); |
| 8700 String::VisitFlat(this, next); | 8689 String::VisitFlat(this, next); |
| 8701 } | 8690 } |
| 8702 | 8691 |
| 8703 ConsStringIteratorOp* const op_; | 8692 ConsStringIterator iter_; |
| 8704 bool is_one_byte_; | 8693 bool is_one_byte_; |
| 8705 int length_; | 8694 int length_; |
| 8706 union { | 8695 union { |
| 8707 const uint8_t* buffer8_; | 8696 const uint8_t* buffer8_; |
| 8708 const uint16_t* buffer16_; | 8697 const uint16_t* buffer16_; |
| 8709 }; | 8698 }; |
| 8710 | 8699 |
| 8711 private: | 8700 private: |
| 8712 DISALLOW_IMPLICIT_CONSTRUCTORS(State); | 8701 DISALLOW_COPY_AND_ASSIGN(State); |
| 8713 }; | 8702 }; |
| 8714 | 8703 |
| 8715 public: | 8704 public: |
| 8716 inline StringComparator(ConsStringIteratorOp* op_1, | 8705 inline StringComparator() {} |
| 8717 ConsStringIteratorOp* op_2) | |
| 8718 : state_1_(op_1), | |
| 8719 state_2_(op_2) { | |
| 8720 } | |
| 8721 | 8706 |
| 8722 template<typename Chars1, typename Chars2> | 8707 template<typename Chars1, typename Chars2> |
| 8723 static inline bool Equals(State* state_1, State* state_2, int to_check) { | 8708 static inline bool Equals(State* state_1, State* state_2, int to_check) { |
| 8724 const Chars1* a = reinterpret_cast<const Chars1*>(state_1->buffer8_); | 8709 const Chars1* a = reinterpret_cast<const Chars1*>(state_1->buffer8_); |
| 8725 const Chars2* b = reinterpret_cast<const Chars2*>(state_2->buffer8_); | 8710 const Chars2* b = reinterpret_cast<const Chars2*>(state_2->buffer8_); |
| 8726 return RawStringComparator<Chars1, Chars2>::compare(a, b, to_check); | 8711 return RawStringComparator<Chars1, Chars2>::compare(a, b, to_check); |
| 8727 } | 8712 } |
| 8728 | 8713 |
| 8729 bool Equals(String* string_1, String* string_2) { | 8714 bool Equals(String* string_1, String* string_2) { |
| 8730 int length = string_1->length(); | 8715 int length = string_1->length(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 8753 // Exit condition. Strings are equal. | 8738 // Exit condition. Strings are equal. |
| 8754 if (length == 0) return true; | 8739 if (length == 0) return true; |
| 8755 state_1_.Advance(to_check); | 8740 state_1_.Advance(to_check); |
| 8756 state_2_.Advance(to_check); | 8741 state_2_.Advance(to_check); |
| 8757 } | 8742 } |
| 8758 } | 8743 } |
| 8759 | 8744 |
| 8760 private: | 8745 private: |
| 8761 State state_1_; | 8746 State state_1_; |
| 8762 State state_2_; | 8747 State state_2_; |
| 8763 DISALLOW_IMPLICIT_CONSTRUCTORS(StringComparator); | 8748 |
| 8749 DISALLOW_COPY_AND_ASSIGN(StringComparator); |
| 8764 }; | 8750 }; |
| 8765 | 8751 |
| 8766 | 8752 |
| 8767 bool String::SlowEquals(String* other) { | 8753 bool String::SlowEquals(String* other) { |
| 8768 DisallowHeapAllocation no_gc; | 8754 DisallowHeapAllocation no_gc; |
| 8769 // Fast check: negative check with lengths. | 8755 // Fast check: negative check with lengths. |
| 8770 int len = length(); | 8756 int len = length(); |
| 8771 if (len != other->length()) return false; | 8757 if (len != other->length()) return false; |
| 8772 if (len == 0) return true; | 8758 if (len == 0) return true; |
| 8773 | 8759 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 8794 // We know the strings are both non-empty. Compare the first chars | 8780 // We know the strings are both non-empty. Compare the first chars |
| 8795 // before we try to flatten the strings. | 8781 // before we try to flatten the strings. |
| 8796 if (this->Get(0) != other->Get(0)) return false; | 8782 if (this->Get(0) != other->Get(0)) return false; |
| 8797 | 8783 |
| 8798 if (IsSeqOneByteString() && other->IsSeqOneByteString()) { | 8784 if (IsSeqOneByteString() && other->IsSeqOneByteString()) { |
| 8799 const uint8_t* str1 = SeqOneByteString::cast(this)->GetChars(); | 8785 const uint8_t* str1 = SeqOneByteString::cast(this)->GetChars(); |
| 8800 const uint8_t* str2 = SeqOneByteString::cast(other)->GetChars(); | 8786 const uint8_t* str2 = SeqOneByteString::cast(other)->GetChars(); |
| 8801 return CompareRawStringContents(str1, str2, len); | 8787 return CompareRawStringContents(str1, str2, len); |
| 8802 } | 8788 } |
| 8803 | 8789 |
| 8804 Isolate* isolate = GetIsolate(); | 8790 StringComparator comparator; |
| 8805 StringComparator comparator(isolate->objects_string_compare_iterator_a(), | |
| 8806 isolate->objects_string_compare_iterator_b()); | |
| 8807 | |
| 8808 return comparator.Equals(this, other); | 8791 return comparator.Equals(this, other); |
| 8809 } | 8792 } |
| 8810 | 8793 |
| 8811 | 8794 |
| 8812 bool String::SlowEquals(Handle<String> one, Handle<String> two) { | 8795 bool String::SlowEquals(Handle<String> one, Handle<String> two) { |
| 8813 // Fast check: negative check with lengths. | 8796 // Fast check: negative check with lengths. |
| 8814 int one_length = one->length(); | 8797 int one_length = one->length(); |
| 8815 if (one_length != two->length()) return false; | 8798 if (one_length != two->length()) return false; |
| 8816 if (one_length == 0) return true; | 8799 if (one_length == 0) return true; |
| 8817 | 8800 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8949 DCHECK(HasHashCode()); | 8932 DCHECK(HasHashCode()); |
| 8950 uint32_t result = field >> kHashShift; | 8933 uint32_t result = field >> kHashShift; |
| 8951 DCHECK(result != 0); // Ensure that the hash value of 0 is never computed. | 8934 DCHECK(result != 0); // Ensure that the hash value of 0 is never computed. |
| 8952 return result; | 8935 return result; |
| 8953 } | 8936 } |
| 8954 | 8937 |
| 8955 | 8938 |
| 8956 bool String::ComputeArrayIndex(uint32_t* index) { | 8939 bool String::ComputeArrayIndex(uint32_t* index) { |
| 8957 int length = this->length(); | 8940 int length = this->length(); |
| 8958 if (length == 0 || length > kMaxArrayIndexSize) return false; | 8941 if (length == 0 || length > kMaxArrayIndexSize) return false; |
| 8959 ConsStringIteratorOp op; | 8942 StringCharacterStream stream(this); |
| 8960 StringCharacterStream stream(this, &op); | |
| 8961 return StringToArrayIndex(&stream, index); | 8943 return StringToArrayIndex(&stream, index); |
| 8962 } | 8944 } |
| 8963 | 8945 |
| 8964 | 8946 |
| 8965 bool String::SlowAsArrayIndex(uint32_t* index) { | 8947 bool String::SlowAsArrayIndex(uint32_t* index) { |
| 8966 if (length() <= kMaxCachedArrayIndexLength) { | 8948 if (length() <= kMaxCachedArrayIndexLength) { |
| 8967 Hash(); // force computation of hash code | 8949 Hash(); // force computation of hash code |
| 8968 uint32_t field = hash_field(); | 8950 uint32_t field = hash_field(); |
| 8969 if ((field & kIsNotArrayIndexMask) != 0) return false; | 8951 if ((field & kIsNotArrayIndexMask) != 0) return false; |
| 8970 // Isolate the array index form the full hash field. | 8952 // Isolate the array index form the full hash field. |
| (...skipping 7498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16469 Handle<DependentCode> codes = | 16451 Handle<DependentCode> codes = |
| 16470 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16452 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
| 16471 DependentCode::kPropertyCellChangedGroup, | 16453 DependentCode::kPropertyCellChangedGroup, |
| 16472 info->object_wrapper()); | 16454 info->object_wrapper()); |
| 16473 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16455 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
| 16474 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16456 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 16475 cell, info->zone()); | 16457 cell, info->zone()); |
| 16476 } | 16458 } |
| 16477 | 16459 |
| 16478 } } // namespace v8::internal | 16460 } } // namespace v8::internal |
| OLD | NEW |