[Cleanup] String::GetChars() should assert against heap allocation
R=jkummerow@chromium.org Bug: v8:8238 Change-Id: Ie28326ebe6c69e194857aed7b5d49cb8e5a40a29 Reviewed-on: https://chromium-review.googlesource.com/c/1349243 Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Reviewed-by: Marja Hölttä <marja@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Michael Stanton <mvstanton@chromium.org> Cr-Commit-Position: refs/heads/master@{#57821}
This commit is contained in:
parent
970fdf3c02
commit
92852e9287
@ -109,6 +109,7 @@ BUILTIN(StringFromCodePoint) {
|
|||||||
isolate->factory()->NewRawTwoByteString(
|
isolate->factory()->NewRawTwoByteString(
|
||||||
static_cast<int>(one_byte_buffer.size() + two_byte_buffer.size())));
|
static_cast<int>(one_byte_buffer.size() + two_byte_buffer.size())));
|
||||||
|
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
CopyChars(result->GetChars(), one_byte_buffer.data(), one_byte_buffer.size());
|
CopyChars(result->GetChars(), one_byte_buffer.data(), one_byte_buffer.size());
|
||||||
CopyChars(result->GetChars() + one_byte_buffer.size(), two_byte_buffer.data(),
|
CopyChars(result->GetChars() + one_byte_buffer.size(), two_byte_buffer.data(),
|
||||||
two_byte_buffer.size());
|
two_byte_buffer.size());
|
||||||
@ -467,6 +468,7 @@ V8_WARN_UNUSED_RESULT static Object* ConvertCase(
|
|||||||
String::FlatContent flat_content = s->GetFlatContent();
|
String::FlatContent flat_content = s->GetFlatContent();
|
||||||
DCHECK(flat_content.IsFlat());
|
DCHECK(flat_content.IsFlat());
|
||||||
bool has_changed_character = false;
|
bool has_changed_character = false;
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
int index_to_first_unprocessed = FastAsciiConvert<Converter::kIsToLower>(
|
int index_to_first_unprocessed = FastAsciiConvert<Converter::kIsToLower>(
|
||||||
reinterpret_cast<char*>(result->GetChars()),
|
reinterpret_cast<char*>(result->GetChars()),
|
||||||
reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()),
|
reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()),
|
||||||
|
@ -34,6 +34,7 @@ class MaybeUtf8 {
|
|||||||
// Why copy? Well, the trace event mechanism requires null-terminated
|
// Why copy? Well, the trace event mechanism requires null-terminated
|
||||||
// strings, the bytes we get from SeqOneByteString are not. buf_ is
|
// strings, the bytes we get from SeqOneByteString are not. buf_ is
|
||||||
// guaranteed to be null terminated.
|
// guaranteed to be null terminated.
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
memcpy(buf_, Handle<SeqOneByteString>::cast(string)->GetChars(), len);
|
memcpy(buf_, Handle<SeqOneByteString>::cast(string)->GetChars(), len);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -664,6 +664,7 @@ MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string,
|
|||||||
NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), String);
|
NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), String);
|
||||||
|
|
||||||
// Copy ASCII portion.
|
// Copy ASCII portion.
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
uint16_t* data = result->GetChars();
|
uint16_t* data = result->GetChars();
|
||||||
for (int i = 0; i < non_ascii_start; i++) {
|
for (int i = 0; i < non_ascii_start; i++) {
|
||||||
*data++ = *ascii_data++;
|
*data++ = *ascii_data++;
|
||||||
@ -677,23 +678,31 @@ MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string,
|
|||||||
MaybeHandle<String> Factory::NewStringFromUtf8SubString(
|
MaybeHandle<String> Factory::NewStringFromUtf8SubString(
|
||||||
Handle<SeqOneByteString> str, int begin, int length,
|
Handle<SeqOneByteString> str, int begin, int length,
|
||||||
PretenureFlag pretenure) {
|
PretenureFlag pretenure) {
|
||||||
const char* ascii_data =
|
Access<UnicodeCache::Utf8Decoder> decoder(
|
||||||
reinterpret_cast<const char*>(str->GetChars() + begin);
|
isolate()->unicode_cache()->utf8_decoder());
|
||||||
int non_ascii_start = String::NonAsciiStart(ascii_data, length);
|
int non_ascii_start;
|
||||||
|
int utf16_length = 0;
|
||||||
|
{
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
|
const char* ascii_data =
|
||||||
|
reinterpret_cast<const char*>(str->GetChars() + begin);
|
||||||
|
non_ascii_start = String::NonAsciiStart(ascii_data, length);
|
||||||
|
if (non_ascii_start < length) {
|
||||||
|
// Non-ASCII and we need to decode.
|
||||||
|
auto non_ascii = Vector<const char>(ascii_data + non_ascii_start,
|
||||||
|
length - non_ascii_start);
|
||||||
|
decoder->Reset(non_ascii);
|
||||||
|
|
||||||
|
utf16_length = static_cast<int>(decoder->Utf16Length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (non_ascii_start >= length) {
|
if (non_ascii_start >= length) {
|
||||||
// If the string is ASCII, we can just make a substring.
|
// If the string is ASCII, we can just make a substring.
|
||||||
// TODO(v8): the pretenure flag is ignored in this case.
|
// TODO(v8): the pretenure flag is ignored in this case.
|
||||||
return NewSubString(str, begin, begin + length);
|
return NewSubString(str, begin, begin + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-ASCII and we need to decode.
|
|
||||||
auto non_ascii = Vector<const char>(ascii_data + non_ascii_start,
|
|
||||||
length - non_ascii_start);
|
|
||||||
Access<UnicodeCache::Utf8Decoder> decoder(
|
|
||||||
isolate()->unicode_cache()->utf8_decoder());
|
|
||||||
decoder->Reset(non_ascii);
|
|
||||||
|
|
||||||
int utf16_length = static_cast<int>(decoder->Utf16Length());
|
|
||||||
DCHECK_GT(utf16_length, 0);
|
DCHECK_GT(utf16_length, 0);
|
||||||
|
|
||||||
// Allocate string.
|
// Allocate string.
|
||||||
@ -704,9 +713,11 @@ MaybeHandle<String> Factory::NewStringFromUtf8SubString(
|
|||||||
|
|
||||||
// Update pointer references, since the original string may have moved after
|
// Update pointer references, since the original string may have moved after
|
||||||
// allocation.
|
// allocation.
|
||||||
ascii_data = reinterpret_cast<const char*>(str->GetChars() + begin);
|
DisallowHeapAllocation no_gc;
|
||||||
non_ascii = Vector<const char>(ascii_data + non_ascii_start,
|
const char* ascii_data =
|
||||||
length - non_ascii_start);
|
reinterpret_cast<const char*>(str->GetChars() + begin);
|
||||||
|
auto non_ascii = Vector<const char>(ascii_data + non_ascii_start,
|
||||||
|
length - non_ascii_start);
|
||||||
|
|
||||||
// Copy ASCII portion.
|
// Copy ASCII portion.
|
||||||
uint16_t* data = result->GetChars();
|
uint16_t* data = result->GetChars();
|
||||||
@ -728,12 +739,14 @@ MaybeHandle<String> Factory::NewStringFromTwoByte(const uc16* string,
|
|||||||
Handle<SeqOneByteString> result;
|
Handle<SeqOneByteString> result;
|
||||||
ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
|
ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
|
||||||
NewRawOneByteString(length, pretenure), String);
|
NewRawOneByteString(length, pretenure), String);
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
CopyChars(result->GetChars(), string, length);
|
CopyChars(result->GetChars(), string, length);
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
Handle<SeqTwoByteString> result;
|
Handle<SeqTwoByteString> result;
|
||||||
ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
|
ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
|
||||||
NewRawTwoByteString(length, pretenure), String);
|
NewRawTwoByteString(length, pretenure), String);
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
CopyChars(result->GetChars(), string, length);
|
CopyChars(result->GetChars(), string, length);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -828,6 +841,7 @@ Handle<String> Factory::AllocateTwoByteInternalizedString(
|
|||||||
answer->set_length(str.length());
|
answer->set_length(str.length());
|
||||||
answer->set_hash_field(hash_field);
|
answer->set_hash_field(hash_field);
|
||||||
DCHECK_EQ(size, answer->Size());
|
DCHECK_EQ(size, answer->Size());
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
|
|
||||||
// Fill in the characters.
|
// Fill in the characters.
|
||||||
MemCopy(answer->GetChars(), str.start(), str.length() * kUC16Size);
|
MemCopy(answer->GetChars(), str.start(), str.length() * kUC16Size);
|
||||||
@ -861,6 +875,7 @@ Handle<String> Factory::AllocateInternalizedStringImpl(T t, int chars,
|
|||||||
answer->set_length(chars);
|
answer->set_length(chars);
|
||||||
answer->set_hash_field(hash_field);
|
answer->set_hash_field(hash_field);
|
||||||
DCHECK_EQ(size, answer->Size());
|
DCHECK_EQ(size, answer->Size());
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
|
|
||||||
if (is_one_byte) {
|
if (is_one_byte) {
|
||||||
WriteOneByteData(t, SeqOneByteString::cast(*answer)->GetChars(), chars);
|
WriteOneByteData(t, SeqOneByteString::cast(*answer)->GetChars(), chars);
|
||||||
@ -876,6 +891,7 @@ Handle<String> Factory::NewInternalizedStringFromUtf8(Vector<const char> str,
|
|||||||
if (IsOneByte(str, chars)) {
|
if (IsOneByte(str, chars)) {
|
||||||
Handle<SeqOneByteString> result =
|
Handle<SeqOneByteString> result =
|
||||||
AllocateRawOneByteInternalizedString(str.length(), hash_field);
|
AllocateRawOneByteInternalizedString(str.length(), hash_field);
|
||||||
|
DisallowHeapAllocation no_allocation;
|
||||||
MemCopy(result->GetChars(), str.start(), str.length());
|
MemCopy(result->GetChars(), str.start(), str.length());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -886,6 +902,7 @@ Handle<String> Factory::NewOneByteInternalizedString(Vector<const uint8_t> str,
|
|||||||
uint32_t hash_field) {
|
uint32_t hash_field) {
|
||||||
Handle<SeqOneByteString> result =
|
Handle<SeqOneByteString> result =
|
||||||
AllocateRawOneByteInternalizedString(str.length(), hash_field);
|
AllocateRawOneByteInternalizedString(str.length(), hash_field);
|
||||||
|
DisallowHeapAllocation no_allocation;
|
||||||
MemCopy(result->GetChars(), str.start(), str.length());
|
MemCopy(result->GetChars(), str.start(), str.length());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -895,6 +912,7 @@ Handle<String> Factory::NewOneByteInternalizedSubString(
|
|||||||
uint32_t hash_field) {
|
uint32_t hash_field) {
|
||||||
Handle<SeqOneByteString> result =
|
Handle<SeqOneByteString> result =
|
||||||
AllocateRawOneByteInternalizedString(length, hash_field);
|
AllocateRawOneByteInternalizedString(length, hash_field);
|
||||||
|
DisallowHeapAllocation no_allocation;
|
||||||
MemCopy(result->GetChars(), string->GetChars() + offset, length);
|
MemCopy(result->GetChars(), string->GetChars() + offset, length);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1052,6 +1070,7 @@ static inline Handle<String> MakeOrFindTwoCharacterString(Isolate* isolate,
|
|||||||
1)); // because of this.
|
1)); // because of this.
|
||||||
Handle<SeqOneByteString> str =
|
Handle<SeqOneByteString> str =
|
||||||
isolate->factory()->NewRawOneByteString(2).ToHandleChecked();
|
isolate->factory()->NewRawOneByteString(2).ToHandleChecked();
|
||||||
|
DisallowHeapAllocation no_allocation;
|
||||||
uint8_t* dest = str->GetChars();
|
uint8_t* dest = str->GetChars();
|
||||||
dest[0] = static_cast<uint8_t>(c1);
|
dest[0] = static_cast<uint8_t>(c1);
|
||||||
dest[1] = static_cast<uint8_t>(c2);
|
dest[1] = static_cast<uint8_t>(c2);
|
||||||
@ -1059,6 +1078,7 @@ static inline Handle<String> MakeOrFindTwoCharacterString(Isolate* isolate,
|
|||||||
} else {
|
} else {
|
||||||
Handle<SeqTwoByteString> str =
|
Handle<SeqTwoByteString> str =
|
||||||
isolate->factory()->NewRawTwoByteString(2).ToHandleChecked();
|
isolate->factory()->NewRawTwoByteString(2).ToHandleChecked();
|
||||||
|
DisallowHeapAllocation no_allocation;
|
||||||
uc16* dest = str->GetChars();
|
uc16* dest = str->GetChars();
|
||||||
dest[0] = c1;
|
dest[0] = c1;
|
||||||
dest[1] = c2;
|
dest[1] = c2;
|
||||||
@ -1188,6 +1208,7 @@ Handle<String> Factory::NewSurrogatePairString(uint16_t lead, uint16_t trail) {
|
|||||||
|
|
||||||
Handle<SeqTwoByteString> str =
|
Handle<SeqTwoByteString> str =
|
||||||
isolate()->factory()->NewRawTwoByteString(2).ToHandleChecked();
|
isolate()->factory()->NewRawTwoByteString(2).ToHandleChecked();
|
||||||
|
DisallowHeapAllocation no_allocation;
|
||||||
uc16* dest = str->GetChars();
|
uc16* dest = str->GetChars();
|
||||||
dest[0] = lead;
|
dest[0] = lead;
|
||||||
dest[1] = trail;
|
dest[1] = trail;
|
||||||
@ -1221,15 +1242,15 @@ Handle<String> Factory::NewProperSubString(Handle<String> str, int begin,
|
|||||||
if (str->IsOneByteRepresentation()) {
|
if (str->IsOneByteRepresentation()) {
|
||||||
Handle<SeqOneByteString> result =
|
Handle<SeqOneByteString> result =
|
||||||
NewRawOneByteString(length).ToHandleChecked();
|
NewRawOneByteString(length).ToHandleChecked();
|
||||||
uint8_t* dest = result->GetChars();
|
|
||||||
DisallowHeapAllocation no_gc;
|
DisallowHeapAllocation no_gc;
|
||||||
|
uint8_t* dest = result->GetChars();
|
||||||
String::WriteToFlat(*str, dest, begin, end);
|
String::WriteToFlat(*str, dest, begin, end);
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
Handle<SeqTwoByteString> result =
|
Handle<SeqTwoByteString> result =
|
||||||
NewRawTwoByteString(length).ToHandleChecked();
|
NewRawTwoByteString(length).ToHandleChecked();
|
||||||
uc16* dest = result->GetChars();
|
|
||||||
DisallowHeapAllocation no_gc;
|
DisallowHeapAllocation no_gc;
|
||||||
|
uc16* dest = result->GetChars();
|
||||||
String::WriteToFlat(*str, dest, begin, end);
|
String::WriteToFlat(*str, dest, begin, end);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -667,6 +667,7 @@ Handle<Object> JsonParser<seq_one_byte>::ParseJsonNumber() {
|
|||||||
int length = position_ - beg_pos;
|
int length = position_ - beg_pos;
|
||||||
double number;
|
double number;
|
||||||
if (seq_one_byte) {
|
if (seq_one_byte) {
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
Vector<const uint8_t> chars(seq_source_->GetChars() + beg_pos, length);
|
Vector<const uint8_t> chars(seq_source_->GetChars() + beg_pos, length);
|
||||||
number = StringToDouble(chars,
|
number = StringToDouble(chars,
|
||||||
NO_FLAGS, // Hex, octal or trailing junk.
|
NO_FLAGS, // Hex, octal or trailing junk.
|
||||||
@ -726,9 +727,13 @@ Handle<String> JsonParser<seq_one_byte>::SlowScanJsonString(
|
|||||||
int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count));
|
int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count));
|
||||||
Handle<StringType> seq_string =
|
Handle<StringType> seq_string =
|
||||||
NewRawString<StringType>(factory(), length, pretenure_);
|
NewRawString<StringType>(factory(), length, pretenure_);
|
||||||
// Copy prefix into seq_str.
|
|
||||||
SinkChar* dest = seq_string->GetChars();
|
{
|
||||||
String::WriteToFlat(*prefix, dest, start, end);
|
DisallowHeapAllocation no_gc;
|
||||||
|
// Copy prefix into seq_str.
|
||||||
|
SinkChar* dest = seq_string->GetChars();
|
||||||
|
String::WriteToFlat(*prefix, dest, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
while (c0_ != '"') {
|
while (c0_ != '"') {
|
||||||
// Check for control character (0x00-0x1F) or unterminated string (<0).
|
// Check for control character (0x00-0x1F) or unterminated string (<0).
|
||||||
@ -879,8 +884,6 @@ Handle<String> JsonParser<seq_one_byte>::ScanJsonString() {
|
|||||||
} else {
|
} else {
|
||||||
hash = static_cast<uint32_t>(length);
|
hash = static_cast<uint32_t>(length);
|
||||||
}
|
}
|
||||||
Vector<const uint8_t> string_vector(seq_source_->GetChars() + position_,
|
|
||||||
length);
|
|
||||||
StringTable string_table = isolate()->heap()->string_table();
|
StringTable string_table = isolate()->heap()->string_table();
|
||||||
uint32_t capacity = string_table->Capacity();
|
uint32_t capacity = string_table->Capacity();
|
||||||
uint32_t entry = StringTable::FirstProbe(hash, capacity);
|
uint32_t entry = StringTable::FirstProbe(hash, capacity);
|
||||||
@ -894,12 +897,16 @@ Handle<String> JsonParser<seq_one_byte>::ScanJsonString() {
|
|||||||
factory()->InternalizeOneByteString(seq_source_, position_, length);
|
factory()->InternalizeOneByteString(seq_source_, position_, length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!element->IsTheHole(isolate()) &&
|
if (!element->IsTheHole(isolate())) {
|
||||||
String::cast(element)->IsOneByteEqualTo(string_vector)) {
|
DisallowHeapAllocation no_gc;
|
||||||
result = Handle<String>(String::cast(element), isolate());
|
Vector<const uint8_t> string_vector(seq_source_->GetChars() + position_,
|
||||||
DCHECK_EQ(result->Hash(),
|
length);
|
||||||
(hash << String::kHashShift) >> String::kHashShift);
|
if (String::cast(element)->IsOneByteEqualTo(string_vector)) {
|
||||||
break;
|
result = Handle<String>(String::cast(element), isolate());
|
||||||
|
DCHECK_EQ(result->Hash(),
|
||||||
|
(hash << String::kHashShift) >> String::kHashShift);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
entry = StringTable::NextProbe(entry, count++, capacity);
|
entry = StringTable::NextProbe(entry, count++, capacity);
|
||||||
}
|
}
|
||||||
@ -929,6 +936,7 @@ Handle<String> JsonParser<seq_one_byte>::ScanJsonString() {
|
|||||||
int length = position_ - beg_pos;
|
int length = position_ - beg_pos;
|
||||||
Handle<String> result =
|
Handle<String> result =
|
||||||
factory()->NewRawOneByteString(length, pretenure_).ToHandleChecked();
|
factory()->NewRawOneByteString(length, pretenure_).ToHandleChecked();
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
uint8_t* dest = SeqOneByteString::cast(*result)->GetChars();
|
uint8_t* dest = SeqOneByteString::cast(*result)->GetChars();
|
||||||
String::WriteToFlat(*source_, dest, beg_pos, position_);
|
String::WriteToFlat(*source_, dest, beg_pos, position_);
|
||||||
|
|
||||||
|
@ -11382,6 +11382,7 @@ void String::WriteToFlat(String* src,
|
|||||||
sinkchar* sink,
|
sinkchar* sink,
|
||||||
int f,
|
int f,
|
||||||
int t) {
|
int t) {
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
String* source = src;
|
String* source = src;
|
||||||
int from = f;
|
int from = f;
|
||||||
int to = t;
|
int to = t;
|
||||||
@ -12361,6 +12362,7 @@ bool String::IsTwoByteEqualTo(Vector<const uc16> str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t String::ComputeAndSetHash(Isolate* isolate) {
|
uint32_t String::ComputeAndSetHash(Isolate* isolate) {
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
// Should only be called if hash code has not yet been computed.
|
// Should only be called if hash code has not yet been computed.
|
||||||
DCHECK(!HasHashCode());
|
DCHECK(!HasHashCode());
|
||||||
|
|
||||||
@ -12386,6 +12388,7 @@ bool String::ComputeArrayIndex(uint32_t* index) {
|
|||||||
|
|
||||||
|
|
||||||
bool String::SlowAsArrayIndex(uint32_t* index) {
|
bool String::SlowAsArrayIndex(uint32_t* index) {
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
if (length() <= kMaxCachedArrayIndexLength) {
|
if (length() <= kMaxCachedArrayIndexLength) {
|
||||||
Hash(); // force computation of hash code
|
Hash(); // force computation of hash code
|
||||||
uint32_t field = hash_field();
|
uint32_t field = hash_field();
|
||||||
@ -16751,6 +16754,7 @@ Handle<String> SeqOneByteSubStringKey::AsHandle(Isolate* isolate) {
|
|||||||
|
|
||||||
|
|
||||||
bool SeqOneByteSubStringKey::IsMatch(Object* string) {
|
bool SeqOneByteSubStringKey::IsMatch(Object* string) {
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
|
Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
|
||||||
return String::cast(string)->IsOneByteEqualTo(chars);
|
return String::cast(string)->IsOneByteEqualTo(chars);
|
||||||
}
|
}
|
||||||
|
@ -239,11 +239,13 @@ class SeqOneByteSubStringKey : public StringTableKey {
|
|||||||
#endif
|
#endif
|
||||||
SeqOneByteSubStringKey(Isolate* isolate, Handle<SeqOneByteString> string,
|
SeqOneByteSubStringKey(Isolate* isolate, Handle<SeqOneByteString> string,
|
||||||
int from, int length)
|
int from, int length)
|
||||||
: StringTableKey(StringHasher::HashSequentialString(
|
: StringTableKey(0), string_(string), from_(from), length_(length) {
|
||||||
string->GetChars() + from, length, isolate->heap()->HashSeed())),
|
// We have to set the hash later.
|
||||||
string_(string),
|
DisallowHeapAllocation no_gc;
|
||||||
from_(from),
|
uint32_t hash = StringHasher::HashSequentialString(
|
||||||
length_(length) {
|
string->GetChars() + from, length, isolate->heap()->HashSeed());
|
||||||
|
set_hash_field(hash);
|
||||||
|
|
||||||
DCHECK_LE(0, length_);
|
DCHECK_LE(0, length_);
|
||||||
DCHECK_LE(from_ + length_, string_->length());
|
DCHECK_LE(from_ + length_, string_->length());
|
||||||
DCHECK(string_->IsSeqOneByteString());
|
DCHECK(string_->IsSeqOneByteString());
|
||||||
@ -384,6 +386,7 @@ String* String::GetUnderlying() {
|
|||||||
template <class Visitor>
|
template <class Visitor>
|
||||||
ConsString* String::VisitFlat(Visitor* visitor, String* string,
|
ConsString* String::VisitFlat(Visitor* visitor, String* string,
|
||||||
const int offset) {
|
const int offset) {
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
int slice_offset = offset;
|
int slice_offset = offset;
|
||||||
const int length = string->length();
|
const int length = string->length();
|
||||||
DCHECK(offset <= length);
|
DCHECK(offset <= length);
|
||||||
@ -474,6 +477,7 @@ Address SeqOneByteString::GetCharsAddress() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* SeqOneByteString::GetChars() {
|
uint8_t* SeqOneByteString::GetChars() {
|
||||||
|
DCHECK(!AllowHeapAllocation::IsAllowed());
|
||||||
return reinterpret_cast<uint8_t*>(GetCharsAddress());
|
return reinterpret_cast<uint8_t*>(GetCharsAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,6 +486,7 @@ Address SeqTwoByteString::GetCharsAddress() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uc16* SeqTwoByteString::GetChars() {
|
uc16* SeqTwoByteString::GetChars() {
|
||||||
|
DCHECK(!AllowHeapAllocation::IsAllowed());
|
||||||
return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
|
return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,6 +257,7 @@ class BufferedCharacterStream : public Utf16CharacterStream {
|
|||||||
buffer_start_ = &buffer_[0];
|
buffer_start_ = &buffer_[0];
|
||||||
buffer_cursor_ = buffer_start_;
|
buffer_cursor_ = buffer_start_;
|
||||||
|
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
Range<uint8_t> range =
|
Range<uint8_t> range =
|
||||||
byte_stream_.GetDataAt(position, runtime_call_stats());
|
byte_stream_.GetDataAt(position, runtime_call_stats());
|
||||||
if (range.length() == 0) {
|
if (range.length() == 0) {
|
||||||
@ -310,6 +311,7 @@ class UnbufferedCharacterStream : public Utf16CharacterStream {
|
|||||||
bool ReadBlock() final {
|
bool ReadBlock() final {
|
||||||
size_t position = pos();
|
size_t position = pos();
|
||||||
buffer_pos_ = position;
|
buffer_pos_ = position;
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
Range<uint16_t> range =
|
Range<uint16_t> range =
|
||||||
byte_stream_.GetDataAt(position, runtime_call_stats());
|
byte_stream_.GetDataAt(position, runtime_call_stats());
|
||||||
buffer_start_ = range.start;
|
buffer_start_ = range.start;
|
||||||
|
@ -154,6 +154,7 @@ int NativeRegExpMacroAssembler::CheckStackGuardState(
|
|||||||
Isolate* isolate, int start_index, bool is_direct_call,
|
Isolate* isolate, int start_index, bool is_direct_call,
|
||||||
Address* return_address, Code re_code, String** subject,
|
Address* return_address, Code re_code, String** subject,
|
||||||
const byte** input_start, const byte** input_end) {
|
const byte** input_start, const byte** input_end) {
|
||||||
|
AllowHeapAllocation allow_allocation;
|
||||||
DCHECK(re_code->raw_instruction_start() <= *return_address);
|
DCHECK(re_code->raw_instruction_start() <= *return_address);
|
||||||
DCHECK(*return_address <= re_code->raw_instruction_end());
|
DCHECK(*return_address <= re_code->raw_instruction_end());
|
||||||
int return_value = 0;
|
int return_value = 0;
|
||||||
@ -249,6 +250,7 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match(
|
|||||||
// String is now either Sequential or External
|
// String is now either Sequential or External
|
||||||
int char_size_shift = is_one_byte ? 0 : 1;
|
int char_size_shift = is_one_byte ? 0 : 1;
|
||||||
|
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
const byte* input_start =
|
const byte* input_start =
|
||||||
StringCharacterPosition(subject_ptr, start_offset + slice_offset);
|
StringCharacterPosition(subject_ptr, start_offset + slice_offset);
|
||||||
int byte_length = char_length << char_size_shift;
|
int byte_length = char_length << char_size_shift;
|
||||||
@ -287,7 +289,10 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Execute(
|
|||||||
|
|
||||||
if (result == EXCEPTION && !isolate->has_pending_exception()) {
|
if (result == EXCEPTION && !isolate->has_pending_exception()) {
|
||||||
// We detected a stack overflow (on the backtrack stack) in RegExp code,
|
// We detected a stack overflow (on the backtrack stack) in RegExp code,
|
||||||
// but haven't created the exception yet.
|
// but haven't created the exception yet. Additionally, we allow heap
|
||||||
|
// allocation because even though it invalidates {input_start} and
|
||||||
|
// {input_end}, we are about to return anyway.
|
||||||
|
AllowHeapAllocation allow_allocation;
|
||||||
isolate->StackOverflow();
|
isolate->StackOverflow();
|
||||||
}
|
}
|
||||||
return static_cast<Result>(result);
|
return static_cast<Result>(result);
|
||||||
|
@ -570,6 +570,7 @@ V8_WARN_UNUSED_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
|
|||||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res);
|
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res);
|
||||||
Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res);
|
Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res);
|
||||||
|
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
for (int index : *indices) {
|
for (int index : *indices) {
|
||||||
// Copy non-matched subject content.
|
// Copy non-matched subject content.
|
||||||
if (subject_pos < index) {
|
if (subject_pos < index) {
|
||||||
@ -739,6 +740,7 @@ V8_WARN_UNUSED_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString(
|
|||||||
int prev = 0;
|
int prev = 0;
|
||||||
int position = 0;
|
int position = 0;
|
||||||
|
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
do {
|
do {
|
||||||
start = current_match[0];
|
start = current_match[0];
|
||||||
end = current_match[1];
|
end = current_match[1];
|
||||||
|
@ -327,6 +327,7 @@ RUNTIME_FUNCTION(Runtime_StringBuilderConcat) {
|
|||||||
Handle<SeqOneByteString> answer;
|
Handle<SeqOneByteString> answer;
|
||||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||||
isolate, answer, isolate->factory()->NewRawOneByteString(length));
|
isolate, answer, isolate->factory()->NewRawOneByteString(length));
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
StringBuilderConcatHelper(*special, answer->GetChars(),
|
StringBuilderConcatHelper(*special, answer->GetChars(),
|
||||||
FixedArray::cast(array->elements()),
|
FixedArray::cast(array->elements()),
|
||||||
array_length);
|
array_length);
|
||||||
@ -335,6 +336,7 @@ RUNTIME_FUNCTION(Runtime_StringBuilderConcat) {
|
|||||||
Handle<SeqTwoByteString> answer;
|
Handle<SeqTwoByteString> answer;
|
||||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||||
isolate, answer, isolate->factory()->NewRawTwoByteString(length));
|
isolate, answer, isolate->factory()->NewRawTwoByteString(length));
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
StringBuilderConcatHelper(*special, answer->GetChars(),
|
StringBuilderConcatHelper(*special, answer->GetChars(),
|
||||||
FixedArray::cast(array->elements()),
|
FixedArray::cast(array->elements()),
|
||||||
array_length);
|
array_length);
|
||||||
@ -552,6 +554,7 @@ RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) {
|
|||||||
Handle<SeqOneByteString> result = isolate->factory()
|
Handle<SeqOneByteString> result = isolate->factory()
|
||||||
->NewRawOneByteString(string_length)
|
->NewRawOneByteString(string_length)
|
||||||
.ToHandleChecked();
|
.ToHandleChecked();
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
JoinSparseArrayWithSeparator<uint8_t>(
|
JoinSparseArrayWithSeparator<uint8_t>(
|
||||||
FixedArray::cast(elements_array->elements()), elements_length,
|
FixedArray::cast(elements_array->elements()), elements_length,
|
||||||
array_length, *separator,
|
array_length, *separator,
|
||||||
@ -561,6 +564,7 @@ RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) {
|
|||||||
Handle<SeqTwoByteString> result = isolate->factory()
|
Handle<SeqTwoByteString> result = isolate->factory()
|
||||||
->NewRawTwoByteString(string_length)
|
->NewRawTwoByteString(string_length)
|
||||||
.ToHandleChecked();
|
.ToHandleChecked();
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
JoinSparseArrayWithSeparator<uc16>(
|
JoinSparseArrayWithSeparator<uc16>(
|
||||||
FixedArray::cast(elements_array->elements()), elements_length,
|
FixedArray::cast(elements_array->elements()), elements_length,
|
||||||
array_length, *separator,
|
array_length, *separator,
|
||||||
|
@ -194,6 +194,7 @@ MaybeHandle<String> Uri::Decode(Isolate* isolate, Handle<String> uri,
|
|||||||
isolate, result, isolate->factory()->NewRawTwoByteString(result_length),
|
isolate, result, isolate->factory()->NewRawTwoByteString(result_length),
|
||||||
String);
|
String);
|
||||||
|
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
CopyChars(result->GetChars(), one_byte_buffer.data(), one_byte_buffer.size());
|
CopyChars(result->GetChars(), one_byte_buffer.data(), one_byte_buffer.size());
|
||||||
CopyChars(result->GetChars() + one_byte_buffer.size(), two_byte_buffer.data(),
|
CopyChars(result->GetChars() + one_byte_buffer.size(), two_byte_buffer.data(),
|
||||||
two_byte_buffer.size());
|
two_byte_buffer.size());
|
||||||
|
@ -1336,6 +1336,7 @@ MaybeHandle<String> ValueDeserializer::ReadTwoByteString() {
|
|||||||
|
|
||||||
// Copy the bytes directly into the new string.
|
// Copy the bytes directly into the new string.
|
||||||
// Warning: this uses host endianness.
|
// Warning: this uses host endianness.
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
memcpy(string->GetChars(), bytes.begin(), bytes.length());
|
memcpy(string->GetChars(), bytes.begin(), bytes.length());
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
@ -1787,6 +1787,7 @@ TEST(OneToTwoByteStringCopy) {
|
|||||||
isolate->factory()->NewStringFromTwoByte(str).ToHandleChecked();
|
isolate->factory()->NewStringFromTwoByte(str).ToHandleChecked();
|
||||||
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
|
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
|
||||||
ft.Call(string1, string2);
|
ft.Call(string1, string2);
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars()[0],
|
CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars()[0],
|
||||||
Handle<SeqTwoByteString>::cast(string2)->GetChars()[0]);
|
Handle<SeqTwoByteString>::cast(string2)->GetChars()[0]);
|
||||||
CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars()[1],
|
CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars()[1],
|
||||||
@ -1818,6 +1819,7 @@ TEST(OneToOneByteStringCopy) {
|
|||||||
isolate->factory()->NewStringFromOneByte(str).ToHandleChecked();
|
isolate->factory()->NewStringFromOneByte(str).ToHandleChecked();
|
||||||
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
|
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
|
||||||
ft.Call(string1, string2);
|
ft.Call(string1, string2);
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars()[0],
|
CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars()[0],
|
||||||
Handle<SeqOneByteString>::cast(string2)->GetChars()[0]);
|
Handle<SeqOneByteString>::cast(string2)->GetChars()[0]);
|
||||||
CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars()[1],
|
CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars()[1],
|
||||||
@ -1849,6 +1851,7 @@ TEST(OneToOneByteStringCopyNonZeroStart) {
|
|||||||
isolate->factory()->NewStringFromOneByte(str).ToHandleChecked();
|
isolate->factory()->NewStringFromOneByte(str).ToHandleChecked();
|
||||||
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
|
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
|
||||||
ft.Call(string1, string2);
|
ft.Call(string1, string2);
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars()[0],
|
CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars()[0],
|
||||||
Handle<SeqOneByteString>::cast(string2)->GetChars()[3]);
|
Handle<SeqOneByteString>::cast(string2)->GetChars()[3]);
|
||||||
CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars()[1],
|
CHECK_EQ(Handle<SeqOneByteString>::cast(string1)->GetChars()[1],
|
||||||
@ -1880,6 +1883,7 @@ TEST(TwoToTwoByteStringCopy) {
|
|||||||
isolate->factory()->NewStringFromTwoByte(str2).ToHandleChecked();
|
isolate->factory()->NewStringFromTwoByte(str2).ToHandleChecked();
|
||||||
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
|
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
|
||||||
ft.Call(string1, string2);
|
ft.Call(string1, string2);
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
CHECK_EQ(Handle<SeqTwoByteString>::cast(string1)->GetChars()[0],
|
CHECK_EQ(Handle<SeqTwoByteString>::cast(string1)->GetChars()[0],
|
||||||
Handle<SeqTwoByteString>::cast(string2)->GetChars()[0]);
|
Handle<SeqTwoByteString>::cast(string2)->GetChars()[0]);
|
||||||
CHECK_EQ(Handle<SeqTwoByteString>::cast(string1)->GetChars()[1],
|
CHECK_EQ(Handle<SeqTwoByteString>::cast(string1)->GetChars()[1],
|
||||||
|
@ -1819,6 +1819,7 @@ TEST(Regress876759) {
|
|||||||
{
|
{
|
||||||
Handle<SeqTwoByteString> raw =
|
Handle<SeqTwoByteString> raw =
|
||||||
factory->NewRawTwoByteString(kLength).ToHandleChecked();
|
factory->NewRawTwoByteString(kLength).ToHandleChecked();
|
||||||
|
DisallowHeapAllocation no_gc;
|
||||||
CopyChars(raw->GetChars(), two_byte_buf, kLength);
|
CopyChars(raw->GetChars(), two_byte_buf, kLength);
|
||||||
parent = raw;
|
parent = raw;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user