| 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 3287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3298 ASSERT(cons->second()->length() == 0); | 3298 ASSERT(cons->second()->length() == 0); |
| 3299 string = cons->first(); | 3299 string = cons->first(); |
| 3300 string_tag = StringShape(string).representation_tag(); | 3300 string_tag = StringShape(string).representation_tag(); |
| 3301 } | 3301 } |
| 3302 if (string_tag == kSeqStringTag) { | 3302 if (string_tag == kSeqStringTag) { |
| 3303 SeqTwoByteString* seq = SeqTwoByteString::cast(string); | 3303 SeqTwoByteString* seq = SeqTwoByteString::cast(string); |
| 3304 return Vector<const uc16>(seq->GetChars() + offset, length); | 3304 return Vector<const uc16>(seq->GetChars() + offset, length); |
| 3305 } | 3305 } |
| 3306 ASSERT(string_tag == kExternalStringTag); | 3306 ASSERT(string_tag == kExternalStringTag); |
| 3307 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); | 3307 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); |
| 3308 // This is a workaround for Chromium bug 9746: http://crbug.com/9746 | |
| 3309 // For external strings with a deleted resource we return a special | |
| 3310 // Vector which will not compare to any string when doing SymbolTable | |
| 3311 // lookups. | |
| 3312 if (ext->resource() == NULL) { | |
| 3313 return Vector<const uc16>(NULL, length); | |
| 3314 } | |
| 3315 const uc16* start = | 3308 const uc16* start = |
| 3316 reinterpret_cast<const uc16*>(ext->resource()->data()); | 3309 reinterpret_cast<const uc16*>(ext->resource()->data()); |
| 3317 return Vector<const uc16>(start + offset, length); | 3310 return Vector<const uc16>(start + offset, length); |
| 3318 } | 3311 } |
| 3319 | 3312 |
| 3320 | 3313 |
| 3321 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, | 3314 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, |
| 3322 RobustnessFlag robust_flag, | 3315 RobustnessFlag robust_flag, |
| 3323 int offset, | 3316 int offset, |
| 3324 int length, | 3317 int length, |
| (...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4121 // Compare the remaining characters that didn't fit into a block. | 4114 // Compare the remaining characters that didn't fit into a block. |
| 4122 for (; i < length; i++) { | 4115 for (; i < length; i++) { |
| 4123 if (a[i] != b[i]) { | 4116 if (a[i] != b[i]) { |
| 4124 return false; | 4117 return false; |
| 4125 } | 4118 } |
| 4126 } | 4119 } |
| 4127 return true; | 4120 return true; |
| 4128 } | 4121 } |
| 4129 | 4122 |
| 4130 | 4123 |
| 4131 // This is a workaround for Chromium bug 9746: http://crbug.com/9746 | |
| 4132 // Returns true if this Vector matches the problem exposed in the bug. | |
| 4133 template <typename T> | |
| 4134 static bool CheckVectorForBug9746(Vector<T> vec) { | |
| 4135 // The problem is that somehow external string entries in the symbol | |
| 4136 // table can have their resources collected while they are still in the | |
| 4137 // table. This should not happen according to the test in the function | |
| 4138 // DisposeExternalString in api.cc, but we have evidence that it does. | |
| 4139 return (vec.start() == NULL) ? true : false; | |
| 4140 } | |
| 4141 | |
| 4142 | |
| 4143 static StringInputBuffer string_compare_buffer_b; | 4124 static StringInputBuffer string_compare_buffer_b; |
| 4144 | 4125 |
| 4145 | 4126 |
| 4146 template <typename IteratorA> | 4127 template <typename IteratorA> |
| 4147 static inline bool CompareStringContentsPartial(IteratorA* ia, String* b) { | 4128 static inline bool CompareStringContentsPartial(IteratorA* ia, String* b) { |
| 4148 if (b->IsFlat()) { | 4129 if (b->IsFlat()) { |
| 4149 if (b->IsAsciiRepresentation()) { | 4130 if (b->IsAsciiRepresentation()) { |
| 4150 VectorIterator<char> ib(b->ToAsciiVector()); | 4131 VectorIterator<char> ib(b->ToAsciiVector()); |
| 4151 return CompareStringContents(ia, &ib); | 4132 return CompareStringContents(ia, &ib); |
| 4152 } else { | 4133 } else { |
| 4153 Vector<const uc16> vb = b->ToUC16Vector(); | 4134 VectorIterator<uc16> ib(b->ToUC16Vector()); |
| 4154 if (CheckVectorForBug9746(vb)) return false; | |
| 4155 VectorIterator<uc16> ib(vb); | |
| 4156 return CompareStringContents(ia, &ib); | 4135 return CompareStringContents(ia, &ib); |
| 4157 } | 4136 } |
| 4158 } else { | 4137 } else { |
| 4159 string_compare_buffer_b.Reset(0, b); | 4138 string_compare_buffer_b.Reset(0, b); |
| 4160 return CompareStringContents(ia, &string_compare_buffer_b); | 4139 return CompareStringContents(ia, &string_compare_buffer_b); |
| 4161 } | 4140 } |
| 4162 } | 4141 } |
| 4163 | 4142 |
| 4164 | 4143 |
| 4165 static StringInputBuffer string_compare_buffer_a; | 4144 static StringInputBuffer string_compare_buffer_a; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 4187 | 4166 |
| 4188 if (this->IsFlat()) { | 4167 if (this->IsFlat()) { |
| 4189 if (IsAsciiRepresentation()) { | 4168 if (IsAsciiRepresentation()) { |
| 4190 Vector<const char> vec1 = this->ToAsciiVector(); | 4169 Vector<const char> vec1 = this->ToAsciiVector(); |
| 4191 if (other->IsFlat()) { | 4170 if (other->IsFlat()) { |
| 4192 if (other->IsAsciiRepresentation()) { | 4171 if (other->IsAsciiRepresentation()) { |
| 4193 Vector<const char> vec2 = other->ToAsciiVector(); | 4172 Vector<const char> vec2 = other->ToAsciiVector(); |
| 4194 return CompareRawStringContents(vec1, vec2); | 4173 return CompareRawStringContents(vec1, vec2); |
| 4195 } else { | 4174 } else { |
| 4196 VectorIterator<char> buf1(vec1); | 4175 VectorIterator<char> buf1(vec1); |
| 4197 Vector<const uc16> vec2 = other->ToUC16Vector(); | 4176 VectorIterator<uc16> ib(other->ToUC16Vector()); |
| 4198 if (CheckVectorForBug9746(vec2)) return false; | |
| 4199 VectorIterator<uc16> ib(vec2); | |
| 4200 return CompareStringContents(&buf1, &ib); | 4177 return CompareStringContents(&buf1, &ib); |
| 4201 } | 4178 } |
| 4202 } else { | 4179 } else { |
| 4203 VectorIterator<char> buf1(vec1); | 4180 VectorIterator<char> buf1(vec1); |
| 4204 string_compare_buffer_b.Reset(0, other); | 4181 string_compare_buffer_b.Reset(0, other); |
| 4205 return CompareStringContents(&buf1, &string_compare_buffer_b); | 4182 return CompareStringContents(&buf1, &string_compare_buffer_b); |
| 4206 } | 4183 } |
| 4207 } else { | 4184 } else { |
| 4208 Vector<const uc16> vec1 = this->ToUC16Vector(); | 4185 Vector<const uc16> vec1 = this->ToUC16Vector(); |
| 4209 if (CheckVectorForBug9746(vec1)) return false; | |
| 4210 if (other->IsFlat()) { | 4186 if (other->IsFlat()) { |
| 4211 if (other->IsAsciiRepresentation()) { | 4187 if (other->IsAsciiRepresentation()) { |
| 4212 VectorIterator<uc16> buf1(vec1); | 4188 VectorIterator<uc16> buf1(vec1); |
| 4213 VectorIterator<char> ib(other->ToAsciiVector()); | 4189 VectorIterator<char> ib(other->ToAsciiVector()); |
| 4214 return CompareStringContents(&buf1, &ib); | 4190 return CompareStringContents(&buf1, &ib); |
| 4215 } else { | 4191 } else { |
| 4216 Vector<const uc16> vec2 = other->ToUC16Vector(); | 4192 Vector<const uc16> vec2(other->ToUC16Vector()); |
| 4217 if (CheckVectorForBug9746(vec2)) return false; | |
| 4218 return CompareRawStringContents(vec1, vec2); | 4193 return CompareRawStringContents(vec1, vec2); |
| 4219 } | 4194 } |
| 4220 } else { | 4195 } else { |
| 4221 VectorIterator<uc16> buf1(vec1); | 4196 VectorIterator<uc16> buf1(vec1); |
| 4222 string_compare_buffer_b.Reset(0, other); | 4197 string_compare_buffer_b.Reset(0, other); |
| 4223 return CompareStringContents(&buf1, &string_compare_buffer_b); | 4198 return CompareStringContents(&buf1, &string_compare_buffer_b); |
| 4224 } | 4199 } |
| 4225 } | 4200 } |
| 4226 } else { | 4201 } else { |
| 4227 string_compare_buffer_a.Reset(0, this); | 4202 string_compare_buffer_a.Reset(0, this); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 4252 } else if (map == Heap::long_ascii_string_map()) { | 4227 } else if (map == Heap::long_ascii_string_map()) { |
| 4253 this->set_map(Heap::undetectable_long_ascii_string_map()); | 4228 this->set_map(Heap::undetectable_long_ascii_string_map()); |
| 4254 return true; | 4229 return true; |
| 4255 } | 4230 } |
| 4256 // Rest cannot be marked as undetectable | 4231 // Rest cannot be marked as undetectable |
| 4257 return false; | 4232 return false; |
| 4258 } | 4233 } |
| 4259 | 4234 |
| 4260 | 4235 |
| 4261 bool String::IsEqualTo(Vector<const char> str) { | 4236 bool String::IsEqualTo(Vector<const char> str) { |
| 4262 // This is a workaround for Chromium bug 9746: http://crbug.com/9746 | |
| 4263 // The problem is that somehow external string entries in the symbol | |
| 4264 // table can have their resources deleted while they are still in the | |
| 4265 // table. This should not happen according to the test in the function | |
| 4266 // DisposeExternalString in api.cc but we have evidence that it does. | |
| 4267 // Thus we add this bailout here. | |
| 4268 StringShape shape(this); | |
| 4269 if (shape.IsExternalTwoByte()) { | |
| 4270 ExternalTwoByteString* ext = ExternalTwoByteString::cast(this); | |
| 4271 if (ext->resource() == NULL) return false; | |
| 4272 } | |
| 4273 | |
| 4274 int slen = length(); | 4237 int slen = length(); |
| 4275 Access<Scanner::Utf8Decoder> decoder(Scanner::utf8_decoder()); | 4238 Access<Scanner::Utf8Decoder> decoder(Scanner::utf8_decoder()); |
| 4276 decoder->Reset(str.start(), str.length()); | 4239 decoder->Reset(str.start(), str.length()); |
| 4277 int i; | 4240 int i; |
| 4278 for (i = 0; i < slen && decoder->has_more(); i++) { | 4241 for (i = 0; i < slen && decoder->has_more(); i++) { |
| 4279 uc32 r = decoder->GetNext(); | 4242 uc32 r = decoder->GetNext(); |
| 4280 if (Get(i) != r) return false; | 4243 if (Get(i) != r) return false; |
| 4281 } | 4244 } |
| 4282 return i == slen && !decoder->has_more(); | 4245 return i == slen && !decoder->has_more(); |
| 4283 } | 4246 } |
| (...skipping 3253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7537 // No break point. | 7500 // No break point. |
| 7538 if (break_point_objects()->IsUndefined()) return 0; | 7501 if (break_point_objects()->IsUndefined()) return 0; |
| 7539 // Single beak point. | 7502 // Single beak point. |
| 7540 if (!break_point_objects()->IsFixedArray()) return 1; | 7503 if (!break_point_objects()->IsFixedArray()) return 1; |
| 7541 // Multiple break points. | 7504 // Multiple break points. |
| 7542 return FixedArray::cast(break_point_objects())->length(); | 7505 return FixedArray::cast(break_point_objects())->length(); |
| 7543 } | 7506 } |
| 7544 #endif | 7507 #endif |
| 7545 | 7508 |
| 7546 } } // namespace v8::internal | 7509 } } // namespace v8::internal |
| OLD | NEW |