Commit 5f5f8e67 authored by yangguo@chromium.org's avatar yangguo@chromium.org

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
parent cf512308
...@@ -186,7 +186,7 @@ Handle<String> Factory::InternalizeOneByteString(Vector<const uint8_t> string) { ...@@ -186,7 +186,7 @@ Handle<String> Factory::InternalizeOneByteString(Vector<const uint8_t> string) {
Handle<String> Factory::InternalizeOneByteString( Handle<String> Factory::InternalizeOneByteString(
Handle<SeqOneByteString> string, int from, int length) { Handle<SeqOneByteString> string, int from, int length) {
SubStringKey<uint8_t> key(string, from, length); SeqOneByteSubStringKey key(string, from, length);
return InternalizeStringWithKey(&key); return InternalizeStringWithKey(&key);
} }
...@@ -203,12 +203,6 @@ Handle<String> Factory::InternalizeStringWithKey(StringTableKey* 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, MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string,
PretenureFlag pretenure) { PretenureFlag pretenure) {
int length = string.length(); int length = string.length();
...@@ -313,6 +307,17 @@ MUST_USE_RESULT Handle<String> Factory::NewOneByteInternalizedString( ...@@ -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( MUST_USE_RESULT Handle<String> Factory::NewTwoByteInternalizedString(
Vector<const uc16> str, Vector<const uc16> str,
uint32_t hash_field) { uint32_t hash_field) {
......
...@@ -164,7 +164,10 @@ class Factory V8_FINAL { ...@@ -164,7 +164,10 @@ class Factory V8_FINAL {
uint32_t hash_field); uint32_t hash_field);
MUST_USE_RESULT Handle<String> NewOneByteInternalizedString( MUST_USE_RESULT Handle<String> NewOneByteInternalizedString(
Vector<const uint8_t> str, 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); uint32_t hash_field);
MUST_USE_RESULT Handle<String> NewTwoByteInternalizedString( MUST_USE_RESULT Handle<String> NewTwoByteInternalizedString(
......
...@@ -533,21 +533,17 @@ class OneByteStringKey : public SequentialStringKey<uint8_t> { ...@@ -533,21 +533,17 @@ class OneByteStringKey : public SequentialStringKey<uint8_t> {
}; };
template<class Char> class SeqOneByteSubStringKey : public HashTableKey {
class SubStringKey : public HashTableKey {
public: public:
SubStringKey(Handle<String> string, int from, int length) SeqOneByteSubStringKey(Handle<SeqOneByteString> string, int from, int length)
: string_(string), from_(from), length_(length) { : string_(string), from_(from), length_(length) {
if (string_->IsSlicedString()) { DCHECK(string_->IsSeqOneByteString());
string_ = Handle<String>(Unslice(*string_, &from_));
}
DCHECK(string_->IsSeqString() || string->IsExternalString());
} }
virtual uint32_t Hash() V8_OVERRIDE { virtual uint32_t Hash() V8_OVERRIDE {
DCHECK(length_ >= 0); DCHECK(length_ >= 0);
DCHECK(from_ + length_ <= string_->length()); DCHECK(from_ + length_ <= string_->length());
const Char* chars = GetChars() + from_; const uint8_t* chars = string_->GetChars() + from_;
hash_field_ = StringHasher::HashSequentialString( hash_field_ = StringHasher::HashSequentialString(
chars, length_, string_->GetHeap()->HashSeed()); chars, length_, string_->GetHeap()->HashSeed());
uint32_t result = hash_field_ >> String::kHashShift; uint32_t result = hash_field_ >> String::kHashShift;
...@@ -563,17 +559,7 @@ class SubStringKey : public HashTableKey { ...@@ -563,17 +559,7 @@ class SubStringKey : public HashTableKey {
virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE; virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE;
private: private:
const Char* GetChars(); Handle<SeqOneByteString> string_;
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_;
int from_; int from_;
int length_; int length_;
uint32_t hash_field_; uint32_t hash_field_;
......
...@@ -13901,56 +13901,19 @@ Handle<Object> TwoByteStringKey::AsHandle(Isolate* isolate) { ...@@ -13901,56 +13901,19 @@ Handle<Object> TwoByteStringKey::AsHandle(Isolate* isolate) {
} }
template<> Handle<Object> SeqOneByteSubStringKey::AsHandle(Isolate* isolate) {
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) {
if (hash_field_ == 0) Hash(); if (hash_field_ == 0) Hash();
Vector<const uint8_t> chars(GetChars() + from_, length_); return isolate->factory()->NewOneByteInternalizedSubString(
return isolate->factory()->NewOneByteInternalizedString(chars, hash_field_); string_, from_, length_, hash_field_);
} }
template<> bool SeqOneByteSubStringKey::IsMatch(Object* string) {
Handle<Object> SubStringKey<uint16_t>::AsHandle(Isolate* isolate) { Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
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_);
return String::cast(string)->IsOneByteEqualTo(chars); 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. // InternalizedStringKey carries a string/internalized-string object as key.
class InternalizedStringKey : public HashTableKey { class InternalizedStringKey : public HashTableKey {
public: public:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment