Make internalized string parser in JSON.parse GC-safe

SubStringKey::AsHandle is not GC-safe because the string backing store
may move.

R=verwaest@chromium.org

Review URL: https://codereview.chromium.org/484703002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23185 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yangguo@chromium.org 2014-08-19 08:53:38 +00:00
parent cf51230881
commit 5f5f8e6724
4 changed files with 27 additions and 70 deletions

View File

@ -186,7 +186,7 @@ Handle<String> Factory::InternalizeOneByteString(Vector<const uint8_t> string) {
Handle<String> Factory::InternalizeOneByteString(
Handle<SeqOneByteString> string, int from, int length) {
SubStringKey<uint8_t> key(string, from, length);
SeqOneByteSubStringKey key(string, from, length);
return InternalizeStringWithKey(&key);
}
@ -203,12 +203,6 @@ Handle<String> Factory::InternalizeStringWithKey(StringTableKey* key) {
}
template Handle<String> Factory::InternalizeStringWithKey<
SubStringKey<uint8_t> > (SubStringKey<uint8_t>* key);
template Handle<String> Factory::InternalizeStringWithKey<
SubStringKey<uint16_t> > (SubStringKey<uint16_t>* key);
MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string,
PretenureFlag pretenure) {
int length = string.length();
@ -313,6 +307,17 @@ MUST_USE_RESULT Handle<String> Factory::NewOneByteInternalizedString(
}
MUST_USE_RESULT Handle<String> Factory::NewOneByteInternalizedSubString(
Handle<SeqOneByteString> string, int offset, int length,
uint32_t hash_field) {
CALL_HEAP_FUNCTION(
isolate(), isolate()->heap()->AllocateOneByteInternalizedString(
Vector<const uint8_t>(string->GetChars() + offset, length),
hash_field),
String);
}
MUST_USE_RESULT Handle<String> Factory::NewTwoByteInternalizedString(
Vector<const uc16> str,
uint32_t hash_field) {

View File

@ -164,8 +164,11 @@ class Factory V8_FINAL {
uint32_t hash_field);
MUST_USE_RESULT Handle<String> NewOneByteInternalizedString(
Vector<const uint8_t> str,
uint32_t hash_field);
Vector<const uint8_t> str, uint32_t hash_field);
MUST_USE_RESULT Handle<String> NewOneByteInternalizedSubString(
Handle<SeqOneByteString> string, int offset, int length,
uint32_t hash_field);
MUST_USE_RESULT Handle<String> NewTwoByteInternalizedString(
Vector<const uc16> str,

View File

@ -533,21 +533,17 @@ class OneByteStringKey : public SequentialStringKey<uint8_t> {
};
template<class Char>
class SubStringKey : public HashTableKey {
class SeqOneByteSubStringKey : public HashTableKey {
public:
SubStringKey(Handle<String> string, int from, int length)
SeqOneByteSubStringKey(Handle<SeqOneByteString> string, int from, int length)
: string_(string), from_(from), length_(length) {
if (string_->IsSlicedString()) {
string_ = Handle<String>(Unslice(*string_, &from_));
}
DCHECK(string_->IsSeqString() || string->IsExternalString());
DCHECK(string_->IsSeqOneByteString());
}
virtual uint32_t Hash() V8_OVERRIDE {
DCHECK(length_ >= 0);
DCHECK(from_ + length_ <= string_->length());
const Char* chars = GetChars() + from_;
const uint8_t* chars = string_->GetChars() + from_;
hash_field_ = StringHasher::HashSequentialString(
chars, length_, string_->GetHeap()->HashSeed());
uint32_t result = hash_field_ >> String::kHashShift;
@ -563,17 +559,7 @@ class SubStringKey : public HashTableKey {
virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE;
private:
const Char* GetChars();
String* Unslice(String* string, int* offset) {
while (string->IsSlicedString()) {
SlicedString* sliced = SlicedString::cast(string);
*offset += sliced->offset();
string = sliced->parent();
}
return string;
}
Handle<String> string_;
Handle<SeqOneByteString> string_;
int from_;
int length_;
uint32_t hash_field_;

View File

@ -13901,56 +13901,19 @@ Handle<Object> TwoByteStringKey::AsHandle(Isolate* isolate) {
}
template<>
const uint8_t* SubStringKey<uint8_t>::GetChars() {
return string_->IsSeqOneByteString()
? SeqOneByteString::cast(*string_)->GetChars()
: ExternalAsciiString::cast(*string_)->GetChars();
}
template<>
const uint16_t* SubStringKey<uint16_t>::GetChars() {
return string_->IsSeqTwoByteString()
? SeqTwoByteString::cast(*string_)->GetChars()
: ExternalTwoByteString::cast(*string_)->GetChars();
}
template<>
Handle<Object> SubStringKey<uint8_t>::AsHandle(Isolate* isolate) {
Handle<Object> SeqOneByteSubStringKey::AsHandle(Isolate* isolate) {
if (hash_field_ == 0) Hash();
Vector<const uint8_t> chars(GetChars() + from_, length_);
return isolate->factory()->NewOneByteInternalizedString(chars, hash_field_);
return isolate->factory()->NewOneByteInternalizedSubString(
string_, from_, length_, hash_field_);
}
template<>
Handle<Object> SubStringKey<uint16_t>::AsHandle(Isolate* isolate) {
if (hash_field_ == 0) Hash();
Vector<const uint16_t> chars(GetChars() + from_, length_);
return isolate->factory()->NewTwoByteInternalizedString(chars, hash_field_);
}
template<>
bool SubStringKey<uint8_t>::IsMatch(Object* string) {
Vector<const uint8_t> chars(GetChars() + from_, length_);
bool SeqOneByteSubStringKey::IsMatch(Object* string) {
Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
return String::cast(string)->IsOneByteEqualTo(chars);
}
template<>
bool SubStringKey<uint16_t>::IsMatch(Object* string) {
Vector<const uint16_t> chars(GetChars() + from_, length_);
return String::cast(string)->IsTwoByteEqualTo(chars);
}
template class SubStringKey<uint8_t>;
template class SubStringKey<uint16_t>;
// InternalizedStringKey carries a string/internalized-string object as key.
class InternalizedStringKey : public HashTableKey {
public: