mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-27 12:10:47 +00:00
opt string table
Signed-off-by: xiongluo <xiongluo@huawei.com> Change-Id: I6f10e8fcb0f9120c2cdba929b9731e4286a6ab8a
This commit is contained in:
parent
76086af929
commit
d622c14fca
@ -21,32 +21,43 @@
|
||||
namespace panda::ecmascript {
|
||||
|
||||
EcmaString *EcmaString::Concat(const EcmaVM *vm,
|
||||
const JSHandle<EcmaString> &left, const JSHandle<EcmaString> &right)
|
||||
const JSHandle<EcmaString> &left, const JSHandle<EcmaString> &right, MemSpaceType type)
|
||||
{
|
||||
// allocator may trig gc and move src, need to hold it
|
||||
EcmaString *strLeft = *left;
|
||||
EcmaString *strRight = *right;
|
||||
uint32_t leftLength = strLeft->GetLength();
|
||||
if (leftLength == 0) {
|
||||
return strRight;
|
||||
}
|
||||
bool compressed = (strLeft->IsUtf8() && strRight->IsUtf8());
|
||||
uint32_t rightLength = strRight->GetLength();
|
||||
if (rightLength == 0) {
|
||||
return strLeft;
|
||||
}
|
||||
|
||||
uint32_t newLength = leftLength + rightLength;
|
||||
if (newLength == 0) {
|
||||
return vm->GetFactory()->GetEmptyString().GetObject<EcmaString>();
|
||||
}
|
||||
|
||||
bool compressed = (strLeft->IsUtf8() && strRight->IsUtf8());
|
||||
if (leftLength == 0) {
|
||||
if (type == MemSpaceType::OLD_SPACE) {
|
||||
Region *objectRegion = Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(*right));
|
||||
if (objectRegion->InYoungSpace()) {
|
||||
return CopyStringToOldSpace(vm, right, rightLength, compressed);
|
||||
}
|
||||
}
|
||||
return strRight;
|
||||
}
|
||||
if (rightLength == 0) {
|
||||
if (type == MemSpaceType::OLD_SPACE) {
|
||||
Region *objectRegion = Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(*left));
|
||||
if (objectRegion->InYoungSpace()) {
|
||||
return CopyStringToOldSpace(vm, left, leftLength, compressed);
|
||||
}
|
||||
}
|
||||
return strLeft;
|
||||
}
|
||||
|
||||
// if the result string is small, make a LineString
|
||||
if (newLength < TreeEcmaString::MIN_TREE_ECMASTRING_LENGTH) {
|
||||
ASSERT(strLeft->IsLineOrConstantString());
|
||||
ASSERT(strRight->IsLineOrConstantString());
|
||||
auto newString = CreateLineString(vm, newLength, compressed);
|
||||
auto newString = CreateLineStringWithSpaceType(vm, newLength, compressed, type);
|
||||
// retrieve strings after gc
|
||||
strLeft = *left;
|
||||
strRight = *right;
|
||||
@ -83,6 +94,38 @@ EcmaString *EcmaString::Concat(const EcmaVM *vm,
|
||||
return CreateTreeString(vm, left, right, newLength, compressed);
|
||||
}
|
||||
|
||||
/* static */
|
||||
EcmaString *EcmaString::CopyStringToOldSpace(const EcmaVM *vm, const JSHandle<EcmaString> &original,
|
||||
uint32_t length, bool compressed)
|
||||
{
|
||||
EcmaString *strOrigin = *original;
|
||||
ASSERT(strOrigin->IsLineOrConstantString());
|
||||
EcmaString *newString = nullptr;
|
||||
if (strOrigin->IsLineString()) {
|
||||
newString = CreateLineStringWithSpaceType(vm, length, compressed, MemSpaceType::OLD_SPACE);
|
||||
} else if (strOrigin->IsConstantString()){
|
||||
return CreateConstantString(vm, strOrigin->GetDataUtf8(), length, MemSpaceType::OLD_SPACE);
|
||||
}
|
||||
strOrigin = *original;
|
||||
if (compressed) {
|
||||
// copy
|
||||
Span<uint8_t> sp(newString->GetDataUtf8Writable(), length);
|
||||
Span<const uint8_t> srcSp(strOrigin->GetDataUtf8(), length);
|
||||
EcmaString::MemCopyChars(sp, length, srcSp, length);
|
||||
} else {
|
||||
// copy left part
|
||||
Span<uint16_t> sp(newString->GetDataUtf16Writable(), length);
|
||||
if (strOrigin->IsUtf8()) {
|
||||
EcmaString::CopyChars(sp.data(), strOrigin->GetDataUtf8(), length);
|
||||
} else {
|
||||
Span<const uint16_t> srcSp(strOrigin->GetDataUtf16(), length);
|
||||
EcmaString::MemCopyChars(sp, length << 1U, srcSp, length << 1U);
|
||||
}
|
||||
}
|
||||
ASSERT_PRINT(compressed == CanBeCompressed(newString), "compressed does not match the real value!");
|
||||
return newString;
|
||||
}
|
||||
|
||||
/* static */
|
||||
EcmaString *EcmaString::FastSubString(const EcmaVM *vm,
|
||||
const JSHandle<EcmaString> &src, uint32_t start, uint32_t length)
|
||||
|
@ -89,8 +89,10 @@ private:
|
||||
const JSHandle<EcmaString> &left, const JSHandle<EcmaString> &right, uint32_t length, bool compressed);
|
||||
static EcmaString *CreateConstantString(const EcmaVM *vm, const uint8_t *utf8Data,
|
||||
size_t length, bool compressed, MemSpaceType type = MemSpaceType::SEMI_SPACE, uint32_t idOffset = 0);
|
||||
static EcmaString *Concat(const EcmaVM *vm,
|
||||
const JSHandle<EcmaString> &left, const JSHandle<EcmaString> &right);
|
||||
static EcmaString *Concat(const EcmaVM *vm, const JSHandle<EcmaString> &left,
|
||||
const JSHandle<EcmaString> &right, MemSpaceType type = MemSpaceType::SEMI_SPACE);
|
||||
static EcmaString *CopyStringToOldSpace(const EcmaVM *vm, const JSHandle<EcmaString> &original,
|
||||
uint32_t length, bool compressed);
|
||||
static EcmaString *FastSubString(const EcmaVM *vm,
|
||||
const JSHandle<EcmaString> &src, uint32_t start, uint32_t length);
|
||||
// require src is LineString
|
||||
@ -759,10 +761,16 @@ public:
|
||||
return EcmaString::CreateFromUtf16(vm, utf16Data, utf16Len, canBeCompress, type);
|
||||
}
|
||||
|
||||
static EcmaString *Concat(const EcmaVM *vm,
|
||||
const JSHandle<EcmaString> &str1Handle, const JSHandle<EcmaString> &str2Handle)
|
||||
static EcmaString *Concat(const EcmaVM *vm, const JSHandle<EcmaString> &str1Handle,
|
||||
const JSHandle<EcmaString> &str2Handle, MemSpaceType type = MemSpaceType::SEMI_SPACE)
|
||||
{
|
||||
return EcmaString::Concat(vm, str1Handle, str2Handle);
|
||||
return EcmaString::Concat(vm, str1Handle, str2Handle, type);
|
||||
}
|
||||
|
||||
static EcmaString *CopyStringToOldSpace(const EcmaVM *vm, const JSHandle<EcmaString> &original,
|
||||
uint32_t length, bool compressed)
|
||||
{
|
||||
return EcmaString::CopyStringToOldSpace(vm, original, length, compressed);
|
||||
}
|
||||
|
||||
// can change src data structure
|
||||
|
@ -86,8 +86,11 @@ void EcmaStringTable::InternString(EcmaString *string)
|
||||
if (EcmaStringAccessor(string).IsInternString()) {
|
||||
return;
|
||||
}
|
||||
// Strings in string table should not be in the young space.
|
||||
ASSERT(!Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(string))->InYoungSpace());
|
||||
ASSERT(EcmaStringAccessor(string).IsLineOrConstantString());
|
||||
table_.emplace(EcmaStringAccessor(string).GetHashcode(), string);
|
||||
auto hashcode = EcmaStringAccessor(string).GetHashcode();
|
||||
table_.emplace(hashcode, string);
|
||||
EcmaStringAccessor(string).SetInternString();
|
||||
}
|
||||
|
||||
@ -105,8 +108,9 @@ EcmaString *EcmaStringTable::GetOrInternString(const JSHandle<EcmaString> &first
|
||||
if (concatString != nullptr) {
|
||||
return concatString;
|
||||
}
|
||||
JSHandle<EcmaString> concatHandle(vm_->GetJSThread(), EcmaStringAccessor::Concat(vm_, firstFlat, secondFlat));
|
||||
concatString = EcmaStringAccessor::Flatten(vm_, concatHandle);
|
||||
JSHandle<EcmaString> concatHandle(vm_->GetJSThread(),
|
||||
EcmaStringAccessor::Concat(vm_, firstFlat, secondFlat, MemSpaceType::OLD_SPACE));
|
||||
concatString = EcmaStringAccessor::FlattenNoGC(vm_, *concatHandle);
|
||||
InternString(concatString);
|
||||
return concatString;
|
||||
}
|
||||
@ -118,7 +122,7 @@ EcmaString *EcmaStringTable::GetOrInternString(const uint8_t *utf8Data, uint32_t
|
||||
return result;
|
||||
}
|
||||
|
||||
result = EcmaStringAccessor::CreateFromUtf8(vm_, utf8Data, utf8Len, canBeCompress);
|
||||
result = EcmaStringAccessor::CreateFromUtf8(vm_, utf8Data, utf8Len, canBeCompress, MemSpaceType::OLD_SPACE);
|
||||
InternString(result);
|
||||
return result;
|
||||
}
|
||||
@ -146,7 +150,7 @@ EcmaString *EcmaStringTable::GetOrInternString(const uint16_t *utf16Data, uint32
|
||||
return result;
|
||||
}
|
||||
|
||||
result = EcmaStringAccessor::CreateFromUtf16(vm_, utf16Data, utf16Len, canBeCompress);
|
||||
result = EcmaStringAccessor::CreateFromUtf16(vm_, utf16Data, utf16Len, canBeCompress, MemSpaceType::OLD_SPACE);
|
||||
InternString(result);
|
||||
return result;
|
||||
}
|
||||
@ -158,7 +162,7 @@ EcmaString *EcmaStringTable::GetOrInternString(EcmaString *string)
|
||||
}
|
||||
JSHandle<EcmaString> strHandle(vm_->GetJSThread(), string);
|
||||
// may gc
|
||||
auto strFlat = EcmaStringAccessor::Flatten(vm_, strHandle);
|
||||
auto strFlat = EcmaStringAccessor::FlattenNoGC(vm_, *strHandle);
|
||||
if (EcmaStringAccessor(strFlat).IsInternString()) {
|
||||
return strFlat;
|
||||
}
|
||||
@ -166,6 +170,15 @@ EcmaString *EcmaStringTable::GetOrInternString(EcmaString *string)
|
||||
if (result != nullptr) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (EcmaStringAccessor(strFlat).IsLineOrConstantString()) {
|
||||
Region *objectRegion = Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(strFlat));
|
||||
if (objectRegion->InYoungSpace()) {
|
||||
JSHandle<EcmaString> resultHandle(vm_->GetJSThread(), strFlat);
|
||||
strFlat = EcmaStringAccessor::CopyStringToOldSpace(vm_,
|
||||
resultHandle, EcmaStringAccessor(strFlat).GetLength(), EcmaStringAccessor(strFlat).IsUtf8());
|
||||
}
|
||||
}
|
||||
InternString(strFlat);
|
||||
return strFlat;
|
||||
}
|
||||
@ -178,6 +191,7 @@ EcmaString *EcmaStringTable::GetOrInternStringWithSpaceType(const uint8_t *utf8D
|
||||
if (result != nullptr) {
|
||||
return result;
|
||||
}
|
||||
type = type == MemSpaceType::NON_MOVABLE ? MemSpaceType::NON_MOVABLE : MemSpaceType::OLD_SPACE;
|
||||
if (canBeCompress) {
|
||||
// Constant string will be created in this branch.
|
||||
result = EcmaStringAccessor::CreateFromUtf8(vm_, utf8Data, utf8Len, canBeCompress, type, isConstantString,
|
||||
@ -196,7 +210,7 @@ EcmaString *EcmaStringTable::GetOrInternStringWithSpaceType(const uint16_t *utf1
|
||||
if (result != nullptr) {
|
||||
return result;
|
||||
}
|
||||
|
||||
type = type == MemSpaceType::NON_MOVABLE ? MemSpaceType::NON_MOVABLE : MemSpaceType::OLD_SPACE;
|
||||
result = EcmaStringAccessor::CreateFromUtf16(vm_, utf16Data, utf16Len, canBeCompress, type);
|
||||
InternString(result);
|
||||
return result;
|
||||
@ -205,8 +219,10 @@ EcmaString *EcmaStringTable::GetOrInternStringWithSpaceType(const uint16_t *utf1
|
||||
void EcmaStringTable::SweepWeakReference(const WeakRootVisitor &visitor)
|
||||
{
|
||||
for (auto it = table_.begin(); it != table_.end();) {
|
||||
// Strings in string table should not be in the young space. Only old gc will sweep string table.
|
||||
auto *object = it->second;
|
||||
auto fwd = visitor(object);
|
||||
ASSERT(!Region::ObjectAddressToRange(object)->InYoungSpace());
|
||||
if (fwd == nullptr) {
|
||||
LOG_ECMA(VERBOSE) << "StringTable: delete string " << std::hex << object;
|
||||
table_.erase(it++);
|
||||
|
@ -249,6 +249,10 @@ bool SemiSpace::AdjustCapacity(size_t allocatedSizeSinceGC)
|
||||
if (initialCapacity_ <= minimumCapacity_) {
|
||||
return false;
|
||||
}
|
||||
double speed = heap_->GetMemController()->GetNewSpaceAllocationThroughputPerMS();
|
||||
if (speed > LOW_ALLOCATION_SPEED_PER_MS) {
|
||||
return false;
|
||||
}
|
||||
size_t newCapacity = initialCapacity_ / GROWING_FACTOR;
|
||||
SetInitialCapacity(std::max(newCapacity, minimumCapacity_));
|
||||
return true;
|
||||
|
@ -60,7 +60,7 @@ static constexpr size_t DEFAULT_MARK_STACK_SIZE = 4_KB;
|
||||
static constexpr double MIN_OBJECT_SURVIVAL_RATE = 0.75;
|
||||
static constexpr double GROW_OBJECT_SURVIVAL_RATE = 0.8;
|
||||
static constexpr double SHRINK_OBJECT_SURVIVAL_RATE = 0.2;
|
||||
|
||||
static constexpr double LOW_ALLOCATION_SPEED_PER_MS = 1000;
|
||||
// Objects which are larger than half of the region size are huge objects.
|
||||
// Regular objects will be allocated on regular regions and migrated on spaces.
|
||||
// They will never be moved to huge object space. So we take half of a regular
|
||||
|
@ -296,8 +296,11 @@ void ParallelEvacuator::UpdateWeakReference()
|
||||
}
|
||||
return header;
|
||||
};
|
||||
if (isFullMark) {
|
||||
// Only old gc will sweep string table.
|
||||
stringTable->SweepWeakReference(gcUpdateWeak);
|
||||
}
|
||||
|
||||
stringTable->SweepWeakReference(gcUpdateWeak);
|
||||
heap_->GetEcmaVM()->GetJSThread()->IterateWeakEcmaGlobalStorage(gcUpdateWeak);
|
||||
heap_->GetEcmaVM()->ProcessReferences(gcUpdateWeak);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user