Serialize adapt shared heap

Description:Serialize adapt shared heap
Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I94V01?from=project-issue

Signed-off-by: dingwen <dingwen6@huawei.com>
Change-Id: Ie0e00fbb7dd854fb8e5f7d2b93d4ffebe1af53a8
This commit is contained in:
dingwen 2024-02-29 21:39:08 +08:00
parent c95533cc50
commit 5b9ef75fed
16 changed files with 300 additions and 18 deletions

View File

@ -137,7 +137,7 @@ group("ark_unittest") {
"ecmascript/pgo_profiler/tests:host_unittest",
"ecmascript/regexp/tests:host_unittest",
"ecmascript/require/tests:host_unittest",
# "ecmascript/serializer/tests:host_unittest",
"ecmascript/serializer/tests:host_unittest",
"ecmascript/snapshot/tests:host_unittest",
"ecmascript/tests:host_unittest",
"ecmascript/ts_types/tests:host_unittest",

View File

@ -325,6 +325,16 @@ public:
return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_READ_ONLY_SPACE;
}
bool InSharedOldSpace() const
{
return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_SHARED_OLD_SPACE;
}
bool InSharedNonMovableSpace() const
{
return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_SHARED_NON_MOVABLE;
}
bool InSharedHugeObjectSpace() const
{
return packedData_.flags_.spaceFlag_ == RegionSpaceFlag::IN_SHARED_HUGE_OBJECT_SPACE;

View File

@ -50,6 +50,7 @@ void SharedGC::Initialize()
void SharedGC::Mark()
{
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "SharedGC::Mark");
sHeap_->GetSharedGCMarker()->MarkSerializeRoots(MAIN_THREAD_INDEX);
Runtime::GetInstance()->GCIterateThreadList([&](JSThread *thread) {
ASSERT(!thread->IsInRunningState());
auto vm = thread->GetEcmaVM();

View File

@ -17,6 +17,7 @@
#include "ecmascript/mem/object_xray.h"
#include "ecmascript/mem/visitor.h"
#include "ecmascript/runtime.h"
namespace panda::ecmascript {
void SharedGCMarker::MarkRoots(uint32_t threadId, EcmaVM *localVm)
@ -32,6 +33,14 @@ void SharedGCMarker::MarkRoots(uint32_t threadId, EcmaVM *localVm)
sWorkManager_->PushWorkNodeToGlobal(threadId, false);
}
void SharedGCMarker::MarkSerializeRoots(uint32_t threadId)
{
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "SharedGCMarker::MarkSerializeRoots");
auto callback =
std::bind(&SharedGCMarker::HandleRoots, this, threadId, std::placeholders::_1, std::placeholders::_2);
Runtime::GetInstance()->IterateSerializeRoot(callback);
}
void SharedGCMarker::ProcessMarkStack(uint32_t threadId)
{
auto cb = [&](ObjectSlot slot) {

View File

@ -31,6 +31,7 @@ public:
void ResetWorkManager(SharedGCWorkManager *workManager);
void MarkRoots(uint32_t threadId, EcmaVM *localVm);
void MarkSerializeRoots(uint32_t threadId);
void ProcessMarkStack(uint32_t threadId);
template <typename Callback>
inline bool VisitBodyInObj(TaggedObject *root, ObjectSlot start, ObjectSlot end, Callback callback);

View File

@ -38,6 +38,11 @@ void SharedSparseSpace::Reset()
liveObjectSize_ = 0;
}
void SharedSparseSpace::ResetTopPointer(uintptr_t top)
{
allocator_->ResetTopPointer(top);
}
// only used in share heap initialize before first vmThread created.
uintptr_t SharedSparseSpace::AllocateWithoutGC(size_t size)
{
@ -71,6 +76,18 @@ uintptr_t SharedSparseSpace::Allocate(JSThread *thread, size_t size, bool allowG
return object;
}
uintptr_t SharedSparseSpace::AllocateNoGCAndExpand([[maybe_unused]] JSThread *thread, size_t size)
{
ASSERT(thread->IsInRunningState());
uintptr_t object = TryAllocate(size);
CHECK_SOBJECT_AND_INC_OBJ_SIZE(size);
if (sweepState_ == SweepState::SWEEPING) {
object = AllocateAfterSweepingCompleted(size);
CHECK_SOBJECT_AND_INC_OBJ_SIZE(size);
}
return object;
}
uintptr_t SharedSparseSpace::TryAllocate(size_t size)
{
LockHolder lock(allocateLock_);
@ -90,7 +107,7 @@ uintptr_t SharedSparseSpace::AllocateWithExpand(JSThread *thread, size_t size)
bool SharedSparseSpace::Expand(JSThread *thread)
{
if (committedSize_ >= maximumCapacity_ + outOfMemoryOvershootSize_) {
if (CommittedSizeExceed()) {
LOG_ECMA_MEM(INFO) << "Expand::Committed size " << committedSize_ << " of Sparse Space is too big. ";
return false;
}
@ -101,6 +118,24 @@ bool SharedSparseSpace::Expand(JSThread *thread)
return true;
}
Region *SharedSparseSpace::AllocateDeserializeRegion(JSThread *thread)
{
Region *region = heapRegionAllocator_->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE, thread, sHeap_);
region->InitializeFreeObjectSets();
return region;
}
void SharedSparseSpace::MergeDeserializeAllocateRegions(const std::vector<Region *> &allocateRegions)
{
LockHolder lock(allocateLock_);
for (auto region : allocateRegions) {
AddRegion(region);
allocator_->AddFree(region);
allocator_->ResetTopPointer(region->GetHighWaterMark());
region->SetHighWaterMark(region->GetEnd());
}
}
uintptr_t SharedSparseSpace::AllocateAfterSweepingCompleted(size_t size)
{
LockHolder lock(allocateLock_);

View File

@ -59,6 +59,12 @@ public:
uintptr_t Allocate(JSThread *thread, size_t size, bool allowGC = true);
// For work deserialize
void ResetTopPointer(uintptr_t top);
uintptr_t AllocateNoGCAndExpand(JSThread *thread, size_t size);
Region *AllocateDeserializeRegion(JSThread *thread);
void MergeDeserializeAllocateRegions(const std::vector<Region *> &allocateRegions);
// For sweeping
void PrepareSweeping();
void AsyncSweep(bool isMain);
@ -91,6 +97,11 @@ public:
liveObjectSize_ -= size;
}
bool CommittedSizeExceed()
{
return committedSize_ >= maximumCapacity_ + outOfMemoryOvershootSize_;
}
size_t GetTotalAllocatedSize() const;
void InvokeAllocationInspector(Address object, size_t size, size_t alignedSize);

View File

@ -166,4 +166,13 @@ void Runtime::ResumeAllThreadsImpl(JSThread *current)
}
}
}
void Runtime::IterateSerializeRoot(const RootVisitor &v)
{
for (auto &it : serializeRootMap_) {
for (auto &rootObj : it.second) {
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&rootObj)));
}
}
}
} // namespace panda::ecmascript

View File

@ -44,6 +44,7 @@ public:
void SuspendAll(JSThread *current);
void ResumeAll(JSThread *current);
void IterateSerializeRoot(const RootVisitor &v);
MutatorLock *GetMutatorLock()
{
@ -81,6 +82,25 @@ public:
return stringTable_.get();
}
uint32_t PushSerializationRoot([[maybe_unused]] JSThread *thread, std::vector<TaggedObject *> &rootSet)
{
ASSERT(thread->IsInManagedState());
LockHolder lock(serializeLock_);
uint32_t index = GetSerializeDataIndex();
ASSERT(serializeRootMap_.find(index) == serializeRootMap_.end());
serializeRootMap_.emplace(index, rootSet);
return index;
}
void RemoveSerializationRoot([[maybe_unused]] JSThread *thread, uint32_t index)
{
ASSERT(thread->IsInManagedState());
LockHolder lock(serializeLock_);
ASSERT(serializeRootMap_.find(index) != serializeRootMap_.end());
serializeRootMap_.erase(index);
serializeDataIndexVector_.emplace_back(index);
}
private:
Runtime() = default;
~Runtime() = default;
@ -90,9 +110,21 @@ private:
void PreInitialization(const EcmaVM *vm);
void PostInitialization(const EcmaVM *vm);
uint32_t GetSerializeDataIndex()
{
if (!serializeDataIndexVector_.empty()) {
uint32_t index = serializeDataIndexVector_.back();
serializeDataIndexVector_.pop_back();
return index;
}
return ++serializeDataIndex_;
}
Mutex threadsLock_;
Mutex serializeLock_;
std::list<JSThread*> threads_;
uint32_t suspendNewCount_ {0};
uint32_t serializeDataIndex_ {0};
MutatorLock mutatorLock_;
const GlobalEnvConstants *globalConstants_ {nullptr};
@ -103,6 +135,8 @@ private:
std::unique_ptr<HeapRegionAllocator> heapRegionAllocator_;
// for stringTable.
std::unique_ptr<EcmaStringTable> stringTable_;
std::unordered_map<uint32_t, std::vector<TaggedObject *>> serializeRootMap_;
std::vector<uint32_t> serializeDataIndexVector_;
// Runtime instance and VMs creation.
static int32_t vmCount_;

View File

@ -33,7 +33,10 @@ namespace panda::ecmascript {
(uint8_t)SerializedObjectSpace::OLD_SPACE: \
case (uint8_t)SerializedObjectSpace::NON_MOVABLE_SPACE: \
case (uint8_t)SerializedObjectSpace::MACHINE_CODE_SPACE: \
case (uint8_t)SerializedObjectSpace::HUGE_SPACE
case (uint8_t)SerializedObjectSpace::HUGE_SPACE: \
case (uint8_t)SerializedObjectSpace::SHARED_OLD_SPACE: \
case (uint8_t)SerializedObjectSpace::SHARED_NON_MOVABLE_SPACE: \
case (uint8_t)SerializedObjectSpace::SHARED_HUGE_SPACE
JSHandle<JSTaggedValue> BaseDeserializer::ReadValue()
{
@ -400,6 +403,12 @@ size_t BaseDeserializer::ReadSingleEncodeData(uint8_t encodeFlag, uintptr_t objA
handledFieldSize = 0;
break;
}
case (uint8_t)EncodeFlag::SHARED_OBJECT: {
JSTaggedType value = data_->ReadJSTaggedType();
objectVector_.push_back(value);
UpdateMaybeWeak(slot, value, GetAndResetWeak());
break;
}
default:
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
@ -435,15 +444,42 @@ uintptr_t BaseDeserializer::RelocateObjectAddr(SerializedObjectSpace space, size
ASSERT(machineCodeRegionIndex_ < regionVector_.size());
machineCodeSpaceBeginAddr_ = regionVector_[machineCodeRegionIndex_++]->GetBegin();
}
res = nonMovableSpaceBeginAddr_;
nonMovableSpaceBeginAddr_ += objSize;
res = machineCodeSpaceBeginAddr_;
machineCodeSpaceBeginAddr_ += objSize;
break;
}
default:
case SerializedObjectSpace::HUGE_SPACE: {
// no gc for this allocate
res = heap_->GetHugeObjectSpace()->Allocate(objSize, thread_);
break;
}
case SerializedObjectSpace::SHARED_OLD_SPACE: {
if (sOldSpaceBeginAddr_ + objSize > AlignUp(sOldSpaceBeginAddr_, DEFAULT_REGION_SIZE)) {
ASSERT(sOldRegionIndex_ < regionVector_.size());
sOldSpaceBeginAddr_ = regionVector_[sOldRegionIndex_++]->GetBegin();
}
res = sOldSpaceBeginAddr_;
sOldSpaceBeginAddr_ += objSize;
break;
}
case SerializedObjectSpace::SHARED_NON_MOVABLE_SPACE: {
if (sNonMovableSpaceBeginAddr_ + objSize > AlignUp(sNonMovableSpaceBeginAddr_, DEFAULT_REGION_SIZE)) {
ASSERT(sNonMovableRegionIndex_ < regionVector_.size());
sNonMovableSpaceBeginAddr_ = regionVector_[sNonMovableRegionIndex_++]->GetBegin();
}
res = sNonMovableSpaceBeginAddr_;
sNonMovableSpaceBeginAddr_ += objSize;
break;
}
case SerializedObjectSpace::SHARED_HUGE_SPACE: {
// no gc for this allocate
res = sheap_->GetHugeObjectSpace()->Allocate(thread_, objSize);
break;
}
default:
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
}
return res;
}
@ -538,6 +574,16 @@ void BaseDeserializer::AllocateToDifferentSpaces()
heap_->GetMachineCodeSpace()->IncreaseLiveObjectSize(machineCodeSpaceSize);
AllocateToMachineCodeSpace(machineCodeSpaceSize);
}
size_t sOldSpaceSize = data_->GetSharedOldSpaceSize();
if (sOldSpaceSize > 0) {
sheap_->GetOldSpace()->IncreaseLiveObjectSize(sOldSpaceSize);
AllocateToSharedOldSpace(sOldSpaceSize);
}
size_t sNonMovableSpaceSize = data_->GetSharedNonMovableSpaceSize();
if (sNonMovableSpaceSize > 0) {
sheap_->GetNonMovableSpace()->IncreaseLiveObjectSize(sNonMovableSpaceSize);
AllocateToSharedNonMovableSpace(sNonMovableSpaceSize);
}
}
void BaseDeserializer::AllocateMultiRegion(SparseSpace *space, size_t spaceObjSize, size_t &regionIndex)
@ -558,6 +604,32 @@ void BaseDeserializer::AllocateMultiRegion(SparseSpace *space, size_t spaceObjSi
space->ResetTopPointer(space->GetCurrentRegion()->GetEnd() - lastRegionRemainSize);
}
Region *BaseDeserializer::AllocateMultiSharedRegion(SharedSparseSpace *space, size_t spaceObjSize, size_t &regionIndex)
{
regionIndex = regionVector_.size();
size_t regionAlignedSize = SerializeData::AlignUpRegionAvailableSize(spaceObjSize);
size_t regionNum = regionAlignedSize / Region::GetRegionAvailableSize();
std::vector<size_t> regionRemainSizeVector = data_->GetRegionRemainSizeVector();
std::vector<Region *> allocateRegions;
while (regionNum > 0) {
if (space->CommittedSizeExceed()) {
LOG_ECMA(FATAL) << "BaseDeserializer::OutOfMemory when deserialize";
}
Region *region = space->AllocateDeserializeRegion(thread_);
if (regionNum == 1) { // 1: Last allocate region
size_t lastRegionRemainSize = regionAlignedSize - spaceObjSize;
region->SetHighWaterMark(space->GetCurrentRegion()->GetEnd() - lastRegionRemainSize);
} else {
region->SetHighWaterMark(region->GetEnd() - regionRemainSizeVector[regionRemainSizeIndex_++]);
}
regionVector_.push_back(region);
allocateRegions.push_back(region);
regionNum--;
}
space->MergeDeserializeAllocateRegions(allocateRegions);
return allocateRegions.front();
}
void BaseDeserializer::AllocateToOldSpace(size_t oldSpaceSize)
{
SparseSpace *space = heap_->GetOldSpace();
@ -603,5 +675,29 @@ void BaseDeserializer::AllocateToMachineCodeSpace(size_t machineCodeSpaceSize)
}
}
void BaseDeserializer::AllocateToSharedOldSpace(size_t sOldSpaceSize)
{
SharedSparseSpace *space = sheap_->GetOldSpace();
uintptr_t object = space->AllocateNoGCAndExpand(thread_, sOldSpaceSize);
if (UNLIKELY(object == 0U)) {
Region *region = AllocateMultiSharedRegion(space, sOldSpaceSize, sOldRegionIndex_);
sOldSpaceBeginAddr_ = region->GetBegin();
} else {
sOldSpaceBeginAddr_ = object;
}
}
void BaseDeserializer::AllocateToSharedNonMovableSpace(size_t sNonMovableSpaceSize)
{
SharedNonMovableSpace *space = sheap_->GetNonMovableSpace();
uintptr_t object = space->AllocateNoGCAndExpand(thread_, sNonMovableSpaceSize);
if (UNLIKELY(object == 0U)) {
Region *region = AllocateMultiSharedRegion(space, sNonMovableSpaceSize, sNonMovableRegionIndex_);
sNonMovableSpaceBeginAddr_ = region->GetBegin();
} else {
sNonMovableSpaceBeginAddr_ = object;
}
}
} // namespace panda::ecmascript

View File

@ -105,7 +105,10 @@ struct JSErrorInfo {
class BaseDeserializer {
public:
explicit BaseDeserializer(JSThread *thread, SerializeData *data, void *hint = nullptr)
: thread_(thread), heap_(const_cast<Heap *>(thread->GetEcmaVM()->GetHeap())), data_(data), engine_(hint) {}
: thread_(thread), heap_(const_cast<Heap *>(thread->GetEcmaVM()->GetHeap())), data_(data), engine_(hint)
{
sheap_ = SharedHeap::GetInstance();
}
~BaseDeserializer()
{
data_->ResetPosition();
@ -137,9 +140,12 @@ private:
void AllocateToDifferentSpaces();
void AllocateMultiRegion(SparseSpace *space, size_t spaceObjSize, size_t &regionIndex);
Region *AllocateMultiSharedRegion(SharedSparseSpace *space, size_t spaceObjSize, size_t &regionIndex);
void AllocateToOldSpace(size_t oldSpaceSize);
void AllocateToNonMovableSpace(size_t nonMovableSpaceSize);
void AllocateToMachineCodeSpace(size_t machineCodeSpaceSize);
void AllocateToSharedOldSpace(size_t sOldSpaceSize);
void AllocateToSharedNonMovableSpace(size_t sNonMovableSpaceSize);
bool GetAndResetWeak()
{
@ -214,16 +220,21 @@ private:
private:
JSThread *thread_;
Heap *heap_;
SharedHeap *sheap_;
SerializeData* data_;
void *engine_;
uintptr_t oldSpaceBeginAddr_ {0};
uintptr_t nonMovableSpaceBeginAddr_ {0};
uintptr_t machineCodeSpaceBeginAddr_ {0};
uintptr_t sOldSpaceBeginAddr_ {0};
uintptr_t sNonMovableSpaceBeginAddr_ {0};
CVector<uintptr_t> objectVector_;
CVector<Region *> regionVector_;
size_t oldRegionIndex_ {0};
size_t nonMovableRegionIndex_ {0};
size_t machineCodeRegionIndex_ {0};
size_t sOldRegionIndex_ {0};
size_t sNonMovableRegionIndex_ {0};
size_t regionRemainSizeIndex_ {0};
bool isWeak_ {false};
bool isTransferArrayBuffer_ {false};

View File

@ -24,8 +24,7 @@ namespace panda::ecmascript {
SerializedObjectSpace BaseSerializer::GetSerializedObjectSpace(TaggedObject *object) const
{
auto region = Region::ObjectAddressToRange(object);
// TODO(lukai) allocateToSharedSpace please!
if (region->InYoungOrOldSpace() || region->InAppSpawnSpace() || region->InSharedHeap()) {
if (region->InYoungOrOldSpace() || region->InAppSpawnSpace()) {
return SerializedObjectSpace::OLD_SPACE;
}
if (region->InNonMovableSpace() || region->InReadOnlySpace()) {
@ -37,6 +36,15 @@ SerializedObjectSpace BaseSerializer::GetSerializedObjectSpace(TaggedObject *obj
if (region->InHugeObjectSpace()) {
return SerializedObjectSpace::HUGE_SPACE;
}
if (region->InSharedOldSpace()) {
return SerializedObjectSpace::SHARED_OLD_SPACE;
}
if (region->InSharedNonMovableSpace()) {
return SerializedObjectSpace::SHARED_NON_MOVABLE_SPACE;
}
if (region->InSharedHugeObjectSpace()) {
return SerializedObjectSpace::SHARED_HUGE_SPACE;
}
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
}
@ -88,6 +96,14 @@ bool BaseSerializer::SerializeRootObject(TaggedObject *object)
return false;
}
void BaseSerializer::SerializeSharedObject(TaggedObject *object)
{
data_->WriteEncodeFlag(EncodeFlag::SHARED_OBJECT);
data_->WriteJSTaggedType(reinterpret_cast<JSTaggedType>(object));
referenceMap_.emplace(object, objectIndex_++);
sharedObjects_.emplace_back(object);
}
bool BaseSerializer::SerializeSpecialObjIndividually(JSType objectType, TaggedObject *root,
ObjectSlot start, ObjectSlot end)
{

View File

@ -50,6 +50,7 @@ protected:
void SerializeTaggedObject(TaggedObject *object);
bool SerializeReference(TaggedObject *object);
bool SerializeRootObject(TaggedObject *object);
void SerializeSharedObject(TaggedObject *object);
template<SerializeType serializeType>
void SerializeObjectField(TaggedObject *object);
bool SerializeSpecialObjIndividually(JSType objectType, TaggedObject *root, ObjectSlot start, ObjectSlot end);
@ -68,6 +69,7 @@ protected:
EcmaVM *vm_;
std::unique_ptr<SerializeData> data_;
CUnorderedMap<TaggedObject *, uint32_t> referenceMap_;
std::vector<TaggedObject *> sharedObjects_;
size_t objectIndex_ {0};
static constexpr size_t PARENT_ENV_SLOT = sizeof(TaggedObject);
static constexpr size_t SCOPE_INFO_SLOT = PARENT_ENV_SLOT * 2; // 2: the second object slot of lexical env

View File

@ -18,19 +18,23 @@
#include "ecmascript/js_tagged_value-inl.h"
#include "ecmascript/mem/dyn_chunk.h"
#include "ecmascript/runtime.h"
#include "ecmascript/snapshot/mem/snapshot_env.h"
namespace panda::ecmascript {
constexpr size_t INITIAL_CAPACITY = 64;
constexpr int CAPACITY_INCREASE_RATE = 2;
enum class EncodeFlag : uint8_t {
// 0x00~0x03 represent new object to different space:
// 0x00~0x06 represent new object to different space:
// 0x00: old space
// 0x01: non movable space
// 0x02: machine code space
// 0x03: huge space
// 0x04: shared old space
// 0x05: shared non movable space
// 0x06: shared huge space
NEW_OBJECT = 0x00,
REFERENCE = 0x04,
REFERENCE = 0x07,
WEAK,
PRIMITIVE,
MULTI_RAW_DATA,
@ -43,6 +47,7 @@ enum class EncodeFlag : uint8_t {
JS_ERROR,
JS_REG_EXP,
JS_FUNCTION_IN_SHARED,
SHARED_OBJECT,
LAST
};
@ -50,7 +55,10 @@ enum class SerializedObjectSpace : uint8_t {
OLD_SPACE = 0,
NON_MOVABLE_SPACE,
MACHINE_CODE_SPACE,
HUGE_SPACE
HUGE_SPACE,
SHARED_OLD_SPACE,
SHARED_NON_MOVABLE_SPACE,
SHARED_HUGE_SPACE
};
enum class SerializeType : uint8_t {
@ -65,6 +73,9 @@ public:
{
regionRemainSizeVector_.clear();
free(buffer_);
if (!incompleteData_) {
Runtime::GetInstance()->RemoveSerializationRoot(thread_, dataIndex_);
}
}
NO_COPY_SEMANTIC(SerializeData);
NO_MOVE_SEMANTIC(SerializeData);
@ -285,6 +296,16 @@ public:
return machineCodeSpaceSize_;
}
size_t GetSharedOldSpaceSize() const
{
return sharedOldSpaceSize_;
}
size_t GetSharedNonMovableSpaceSize() const
{
return sharedNonMovableSpaceSize_;
}
void CalculateSerializedObjectSize(SerializedObjectSpace space, size_t objectSize)
{
switch (space) {
@ -297,6 +318,12 @@ public:
case SerializedObjectSpace::MACHINE_CODE_SPACE:
AlignSpaceObjectSize(machineCodeSpaceSize_, objectSize);
break;
case SerializedObjectSpace::SHARED_OLD_SPACE:
AlignSpaceObjectSize(sharedOldSpaceSize_, objectSize);
break;
case SerializedObjectSpace::SHARED_NON_MOVABLE_SPACE:
AlignSpaceObjectSize(sharedNonMovableSpaceSize_, objectSize);
break;
default:
break;
}
@ -318,12 +345,23 @@ public:
position_ = 0;
}
void SetDataIndex(uint32_t dataIndex)
{
dataIndex_ = dataIndex;
}
uint32_t GetDataIndex() const
{
return dataIndex_;
}
private:
static constexpr size_t U8_SIZE = 1;
static constexpr size_t U16_SIZE = 2;
static constexpr size_t U32_SIZE = 4;
static constexpr size_t U64_SIZE = 8;
JSThread *thread_;
uint32_t dataIndex_;
uint8_t *buffer_ = nullptr;
uint64_t sizeLimit_ = 0;
size_t bufferSize_ = 0;
@ -331,6 +369,8 @@ private:
size_t oldSpaceSize_ {0};
size_t nonMovableSpaceSize_ {0};
size_t machineCodeSpaceSize_ {0};
size_t sharedOldSpaceSize_ {0};
size_t sharedNonMovableSpaceSize_ {0};
size_t position_ {0};
bool incompleteData_ {false};
std::vector<size_t> regionRemainSizeVector_;

View File

@ -120,7 +120,7 @@ public:
ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
EXPECT_FALSE(res.IsEmpty());
EXPECT_TRUE(res->IsLineString());
EXPECT_TRUE(res->IsTreeString());
Destroy();
}
@ -134,7 +134,7 @@ public:
ecmaVm->CollectGarbage(TriggerGCType::OLD_GC);
EXPECT_FALSE(res.IsEmpty());
EXPECT_TRUE(res->IsLineString());
EXPECT_TRUE(res->IsSlicedString());
Destroy();
}

View File

@ -126,6 +126,11 @@ bool ValueSerializer::WriteValue(JSThread *thread,
data_->SetIncompleteData(true);
return false;
}
// Push share root object to runtime map
if (!sharedObjects_.empty()) {
uint32_t index = Runtime::GetInstance()->PushSerializationRoot(thread_, sharedObjects_);
data_->SetDataIndex(index);
}
size_t maxSerializerSize = vm_->GetEcmaParamConfiguration().GetMaxJSSerializerSize();
if (data_->Size() > maxSerializerSize) {
LOG_ECMA(ERROR) << "The serialization data size has exceed limit Size, current size is: " << data_->Size()
@ -151,6 +156,12 @@ void ValueSerializer::SerializeObjectImpl(TaggedObject *object, bool isWeak)
if (SerializeReference(object) || SerializeRootObject(object)) {
return;
}
Region *region = Region::ObjectAddressToRange(object);
if (object->GetClass()->IsString() || region->InSharedReadOnlySpace() ||
(serializeSharedEvent_ == 0 && region->InSharedHeap())) {
SerializeSharedObject(object);
return;
}
if (object->GetClass()->IsNativeBindingObject()) {
SerializeNativeBindingObject(object);
return;
@ -180,10 +191,6 @@ void ValueSerializer::SerializeObjectImpl(TaggedObject *object, bool isWeak)
array->SetTrackInfo(thread_, JSTaggedValue::Undefined());
break;
}
case JSType::TREE_STRING:
case JSType::SLICED_STRING:
object = EcmaStringAccessor::FlattenNoGC(vm_, EcmaString::Cast(object));
break;
case JSType::JS_REG_EXP:
SerializeJSRegExpPrologue(reinterpret_cast<JSRegExp *>(object));
break;