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:
parent
cf51230881
commit
5f5f8e6724
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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_;
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user