/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/compiler/common-utils.cc
98 строк
4 KB
Michaël Zasso
deps: update V8 to 14.1.146.11
04 окт 2025, 19:47
Не верифицирован
04 окт 2025, 19:47
7772a2d
Код
Авторство
О чём код?
// Copyright 2025 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/compiler/common-utils.h" #include "src/compiler/js-heap-broker.h" #include "src/heap/local-heap.h" #include "src/objects/string-inl.h" namespace v8::internal::compiler::utils { // Concatenates {left} and {right}. The result is fairly similar to creating a // new ConsString with {left} and {right} and then flattening it, which we don't // do because String::Flatten does not support background threads. Rather than // implementing a full String::Flatten for background threads, we preferred to // implement this Concatenate function, which, unlike String::Flatten, doesn't // need to replace ConsStrings by ThinStrings. MaybeHandle<String> ConcatenateStrings(Handle<String> left, Handle<String> right, JSHeapBroker* broker) { if (left->length() == 0) return right; if (right->length() == 0) return left; if (left->length() + right->length() > String::kMaxLength) { return {}; } // Repeated concatenations have a quadratic cost (eg, "s+=a;s+=b;s+=c;..."). // Rather than doing static analysis to determine how many concatenations we // there are and how many uses the result of each concatenation have, we // generate ConsString when the result of the concatenation would have more // than {kConstantStringFlattenMaxSize} characters, and flattened SeqString // otherwise. // TODO(dmercadier): ideally, we would like to get rid of this constant, and // always flatten. This requires some care to avoid the quadratic worst-case. constexpr int32_t kConstantStringFlattenMaxSize = 100; int32_t length = left->length() + right->length(); if (length > kConstantStringFlattenMaxSize) { return broker->local_isolate_or_isolate() ->factory() ->NewConsString(left, right, AllocationType::kOld) .ToHandleChecked(); } // If one of the string is not in readonly space, then we need a // SharedStringAccessGuardIfNeeded before accessing its content. bool require_guard = SharedStringAccessGuardIfNeeded::IsNeeded( *left, broker->local_isolate_or_isolate()) || SharedStringAccessGuardIfNeeded::IsNeeded( *right, broker->local_isolate_or_isolate()); // Check string representation of both strings. This does not require the // SharedStringAccessGuardIfNeeded as the representation is stable. const bool result_is_one_byte_string = left->IsOneByteRepresentation() && right->IsOneByteRepresentation(); if (result_is_one_byte_string) { // {left} and {right} are 1-byte ==> the result will be 1-byte. // Note that we need a canonical handle, because some callers // (JSNativeContextSpecialization) use the handle's address, // which is meaningless if the handle isn't canonical. Handle<SeqOneByteString> flat = broker->CanonicalPersistentHandle( broker->local_isolate_or_isolate() ->factory() ->NewRawOneByteString(length, AllocationType::kOld) .ToHandleChecked()); DisallowGarbageCollection no_gc; SharedStringAccessGuardIfNeeded access_guard( require_guard ? broker->local_isolate_or_isolate() : nullptr); String::WriteToFlat(*left, flat->GetChars(no_gc, access_guard), 0, left->length(), access_guard); String::WriteToFlat(*right, flat->GetChars(no_gc, access_guard) + left->length(), 0, right->length(), access_guard); return flat; } // One (or both) of {left} and {right} is 2-byte ==> the result will be // 2-byte. Handle<SeqTwoByteString> flat = broker->CanonicalPersistentHandle( broker->local_isolate_or_isolate() ->factory() ->NewRawTwoByteString(length, AllocationType::kOld) .ToHandleChecked()); DisallowGarbageCollection no_gc; SharedStringAccessGuardIfNeeded access_guard( require_guard ? broker->local_isolate_or_isolate() : nullptr); String::WriteToFlat(*left, flat->GetChars(no_gc, access_guard), 0, left->length(), access_guard); String::WriteToFlat(*right, flat->GetChars(no_gc, access_guard) + left->length(), 0, right->length(), access_guard); return flat; } } // namespace v8::internal::compiler::utils