Index: src/objects.cc |
=================================================================== |
--- src/objects.cc (revision 1687) |
+++ src/objects.cc (working copy) |
@@ -3301,6 +3301,13 @@ |
} |
ASSERT(string_tag == kExternalStringTag); |
ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); |
+ // This is a workaround for Chromium bug 9746: http://crbug.com/9746 |
+ // For external strings with a deleted resource we return a special |
+ // Vector which will not compare to any string when doing SymbolTable |
+ // lookups. |
+ if (ext->resource() == NULL) { |
+ return Vector<const uc16>(NULL, length); |
+ } |
const uc16* start = |
reinterpret_cast<const uc16*>(ext->resource()->data()); |
return Vector<const uc16>(start + offset, length); |
@@ -4117,6 +4124,18 @@ |
} |
+// This is a workaround for Chromium bug 9746: http://crbug.com/9746 |
+// Returns true if this Vector matches the problem exposed in the bug. |
+template <typename T> |
+static bool CheckVectorForBug9746(Vector<T> vec) { |
+ // The problem is that somehow external string entries in the symbol |
+ // table can have their resources collected while they are still in the |
+ // table. This should not happen according to the test in the function |
+ // DisposeExternalString in api.cc, but we have evidence that it does. |
+ return (vec.start() == NULL) ? true : false; |
+} |
+ |
+ |
static StringInputBuffer string_compare_buffer_b; |
@@ -4127,7 +4146,9 @@ |
VectorIterator<char> ib(b->ToAsciiVector()); |
return CompareStringContents(ia, &ib); |
} else { |
- VectorIterator<uc16> ib(b->ToUC16Vector()); |
+ Vector<const uc16> vb = b->ToUC16Vector(); |
+ if (CheckVectorForBug9746(vb)) return false; |
+ VectorIterator<uc16> ib(vb); |
return CompareStringContents(ia, &ib); |
} |
} else { |
@@ -4169,7 +4190,9 @@ |
return CompareRawStringContents(vec1, vec2); |
} else { |
VectorIterator<char> buf1(vec1); |
- VectorIterator<uc16> ib(other->ToUC16Vector()); |
+ Vector<const uc16> vec2 = other->ToUC16Vector(); |
+ if (CheckVectorForBug9746(vec2)) return false; |
+ VectorIterator<uc16> ib(vec2); |
return CompareStringContents(&buf1, &ib); |
} |
} else { |
@@ -4179,13 +4202,15 @@ |
} |
} else { |
Vector<const uc16> vec1 = this->ToUC16Vector(); |
+ if (CheckVectorForBug9746(vec1)) return false; |
if (other->IsFlat()) { |
if (StringShape(other).IsAsciiRepresentation()) { |
VectorIterator<uc16> buf1(vec1); |
VectorIterator<char> ib(other->ToAsciiVector()); |
return CompareStringContents(&buf1, &ib); |
} else { |
- Vector<const uc16> vec2(other->ToUC16Vector()); |
+ Vector<const uc16> vec2 = other->ToUC16Vector(); |
+ if (CheckVectorForBug9746(vec2)) return false; |
return CompareRawStringContents(vec1, vec2); |
} |
} else { |
@@ -4230,6 +4255,18 @@ |
bool String::IsEqualTo(Vector<const char> str) { |
+ // This is a workaround for Chromium bug 9746: http://crbug.com/9746 |
+ // The problem is that somehow external string entries in the symbol |
+ // table can have their resources deleted while they are still in the |
+ // table. This should not happen according to the test in the function |
+ // DisposeExternalString in api.cc but we have evidence that it does. |
+ // Thus we add this bailout here. |
+ StringShape shape(this); |
+ if (shape.IsExternalTwoByte()) { |
+ ExternalTwoByteString* ext = ExternalTwoByteString::cast(this); |
+ if (ext->resource() == NULL) return false; |
+ } |
+ |
int slen = length(); |
Access<Scanner::Utf8Decoder> decoder(Scanner::utf8_decoder()); |
decoder->Reset(str.start(), str.length()); |