!9136 Add unit tests

Merge pull request !9136 from lvninglei/master
This commit is contained in:
openharmony_ci 2024-09-07 18:46:53 +00:00 committed by Gitee
commit dfc2b50b76
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
16 changed files with 190 additions and 96 deletions

View File

@ -23,7 +23,7 @@ Chunk::Chunk(NativeAreaAllocator *allocator) : allocator_(allocator) {}
Area *Chunk::NewArea(size_t size)
{
auto area = allocator_->AllocateArea(size);
if (area == nullptr) {
if (area == nullptr) { // LOCV_EXCL_BR_LINE
LOG_ECMA_MEM(FATAL) << "OOM Chunk : NewArea area is nullptr";
UNREACHABLE();
}
@ -53,13 +53,13 @@ uintptr_t Chunk::Expand(size_t size)
newSize = std::max(minNewSize, MAX_CHUNK_AREA_SIZE);
}
if (newSize > static_cast<size_t>(std::numeric_limits<int>::max())) {
if (newSize > static_cast<size_t>(std::numeric_limits<int>::max())) { // LOCV_EXCL_BR_LINE
LOG_ECMA_MEM(FATAL) << "OOM chunk : newSize is "<< newSize << ", size is " << size;
UNREACHABLE();
}
Area *area = NewArea(newSize);
if (area == nullptr) {
if (area == nullptr) { // LOCV_EXCL_BR_LINE
LOG_ECMA_MEM(FATAL) << "OOM chunk : NewArea area is nullptr";
UNREACHABLE();
}

View File

@ -111,7 +111,7 @@ void SharedHeap::ForceCollectGarbageWithoutDaemonThread(TriggerGCType gcType, GC
sharedFullGC_->RunPhases();
break;
}
default:
default: // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
break;
@ -382,7 +382,7 @@ void SharedHeap::DaemonCollectGarbage([[maybe_unused]]TriggerGCType gcType, [[ma
sharedFullGC_->RunPhases();
break;
}
default:
default: // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
break;
@ -1178,7 +1178,7 @@ void Heap::CollectGarbage(TriggerGCType gcType, GCReason reason)
fullGC_->SetForAppSpawn(true);
fullGC_->RunPhasesForAppSpawn();
break;
default:
default: // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
break;
@ -2475,7 +2475,7 @@ bool Heap::ParallelGCTask::Run(uint32_t threadIndex)
case ParallelGCTaskPhase::CONCURRENT_HANDLE_OLD_TO_NEW_TASK:
heap_->GetNonMovableMarker()->ProcessOldToNew(threadIndex);
break;
default:
default: // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "this branch is unreachable, type: " << static_cast<int>(taskPhase_);
UNREACHABLE();
}

View File

@ -24,7 +24,7 @@ constexpr size_t PANDA_POOL_ALIGNMENT_IN_BYTES = 256_KB;
Region *HeapRegionAllocator::AllocateAlignedRegion(Space *space, size_t capacity, JSThread* thread, BaseHeap *heap,
bool isFresh)
{
if (capacity == 0) {
if (capacity == 0) { // LOCV_EXCL_BR_LINE
LOG_ECMA_MEM(FATAL) << "capacity must have a size bigger than 0";
UNREACHABLE();
}
@ -41,7 +41,7 @@ Region *HeapRegionAllocator::AllocateAlignedRegion(Space *space, size_t capacity
isRegular, isMachineCode,
Jit::GetInstance()->IsEnableJitFort());
void *mapMem = pool.GetMem();
if (mapMem == nullptr) {
if (mapMem == nullptr) { // LOCV_EXCL_BR_LINE
if (thread != nullptr) {
heap->ThrowOutOfMemoryErrorForDefault(thread, DEFAULT_REGION_SIZE,
"HeapRegionAllocator::AllocateAlignedRegion", false);
@ -50,7 +50,7 @@ Region *HeapRegionAllocator::AllocateAlignedRegion(Space *space, size_t capacity
UNREACHABLE();
}
#if ECMASCRIPT_ENABLE_ZAP_MEM
if (memset_s(mapMem, capacity, 0, capacity) != EOK) {
if (memset_s(mapMem, capacity, 0, capacity) != EOK) { // LOCV_EXCL_BR_LINE
LOG_FULL(FATAL) << "memset_s failed";
UNREACHABLE();
}
@ -81,7 +81,7 @@ void HeapRegionAllocator::FreeRegion(Region *region, size_t cachedSize)
region->Invalidate();
region->ClearMembers();
#if ECMASCRIPT_ENABLE_ZAP_MEM
if (memset_s(ToVoidPtr(allocateBase), size, INVALID_VALUE, size) != EOK) {
if (memset_s(ToVoidPtr(allocateBase), size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE
LOG_FULL(FATAL) << "memset_s failed";
UNREACHABLE();
}

View File

@ -49,7 +49,7 @@ void IncrementalMarker::TriggerIncrementalMark(int64_t idleMicroSec)
RecordIdleTime(idleMicroSec, startTime);
PrintGCIdleUsageStatistic();
break;
default:
default: // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
}

View File

@ -117,7 +117,7 @@ MemDesc *JitFort::RecordLiveJitCodeNoLock(uintptr_t addr, size_t size, bool inst
LOG_JIT(DEBUG) << "RecordLiveJitCode duplicate " << (void *)addr << " size " << size;
return nullptr;
}
if (liveJitCodeBlks_[i]->GetBegin() == addr) {
if (liveJitCodeBlks_[i]->GetBegin() == addr) { // LOCV_EXCL_BR_LINE
LOG_JIT(FATAL) << "RecordLiveJitCode duplicate addr " << std::hex << addr << std::dec << " size " <<
size << " existing entry size " << liveJitCodeBlks_[i]->Available() << std::endl;
return nullptr;
@ -210,7 +210,7 @@ void JitFort::CollectFreeRanges(JitFortRegion *region)
<< " freeEnd = "<< (void*)freeEnd
<< " desc->GetBegin() = " << (void *)(desc->GetBegin())
<< " desc->GetEnd() = " << (void *)(desc->GetEnd());
if (freeStart != freeEnd && freeEnd <= freeStart) {
if (freeStart != freeEnd && freeEnd <= freeStart) { // LOCV_EXCL_BR_LINE
LOG_JIT(FATAL) << "CollectFreeRanges Abort: freeEnd smaller than freeStart";
return;
}

View File

@ -31,7 +31,7 @@ LinearSpace::LinearSpace(Heap *heap, MemSpaceType type, size_t initialCapacity,
uintptr_t LinearSpace::Allocate(size_t size, bool isPromoted)
{
#if ECMASCRIPT_ENABLE_THREAD_STATE_CHECK
if (UNLIKELY(!localHeap_->GetJSThread()->IsInRunningStateOrProfiling())) {
if (UNLIKELY(!localHeap_->GetJSThread()->IsInRunningStateOrProfiling())) { // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "Allocate must be in jsthread running state";
UNREACHABLE();
}

View File

@ -24,7 +24,7 @@ namespace panda::ecmascript {
Area *NativeAreaAllocator::AllocateArea(size_t capacity)
{
size_t headerSize = sizeof(Area);
if (capacity < headerSize) {
if (capacity < headerSize) { // LOCV_EXCL_BR_LINE
LOG_ECMA_MEM(FATAL) << "capacity must have a size not less than sizeof Area.";
UNREACHABLE();
}
@ -35,13 +35,13 @@ Area *NativeAreaAllocator::AllocateArea(size_t capacity)
}
// NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
void *mem = malloc(capacity);
if (mem == nullptr) {
if (mem == nullptr) { // LOCV_EXCL_BR_LINE
LOG_ECMA_MEM(FATAL) << "malloc failed, current alloc size = " << capacity
<< ", total allocated size = " << nativeMemoryUsage_.load(std::memory_order_relaxed);
UNREACHABLE();
}
#if ECMASCRIPT_ENABLE_ZAP_MEM
if (memset_s(mem, capacity, 0, capacity) != EOK) {
if (memset_s(mem, capacity, 0, capacity) != EOK) { // LOCV_EXCL_BR_LINE
LOG_FULL(FATAL) << "memset_s failed";
UNREACHABLE();
}
@ -65,7 +65,7 @@ void NativeAreaAllocator::FreeArea(Area *area)
auto size = area->GetSize() + sizeof(Area);
DecreaseNativeMemoryUsage(size);
#if ECMASCRIPT_ENABLE_ZAP_MEM
if (memset_s(area, size, INVALID_VALUE, size) != EOK) {
if (memset_s(area, size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE
LOG_FULL(FATAL) << "memset_s failed";
UNREACHABLE();
}
@ -81,7 +81,7 @@ void NativeAreaAllocator::Free(void *mem, size_t size)
}
DecreaseNativeMemoryUsage(size);
#if ECMASCRIPT_ENABLE_ZAP_MEM
if (memset_s(mem, size, INVALID_VALUE, size) != EOK) {
if (memset_s(mem, size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE
LOG_FULL(FATAL) << "memset_s failed";
UNREACHABLE();
}
@ -92,19 +92,19 @@ void NativeAreaAllocator::Free(void *mem, size_t size)
void *NativeAreaAllocator::AllocateBuffer(size_t size)
{
if (size == 0) {
if (size == 0) { // LOCV_EXCL_BR_LINE
LOG_ECMA_MEM(FATAL) << "size must have a size bigger than 0";
UNREACHABLE();
}
// NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
void *ptr = malloc(size);
if (ptr == nullptr) {
if (ptr == nullptr) { // LOCV_EXCL_BR_LINE
LOG_ECMA_MEM(FATAL) << "malloc failed, current alloc size = " << size
<< ", total allocated size = " << nativeMemoryUsage_.load(std::memory_order_relaxed);
UNREACHABLE();
}
#if ECMASCRIPT_ENABLE_ZAP_MEM
if (memset_s(ptr, size, INVALID_VALUE, size) != EOK) {
if (memset_s(ptr, size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE
LOG_FULL(FATAL) << "memset_s failed";
UNREACHABLE();
}
@ -122,7 +122,7 @@ void NativeAreaAllocator::FreeBuffer(void *mem)
DecreaseNativeMemoryUsage(size);
#if ECMASCRIPT_ENABLE_ZAP_MEM
if (memset_s(mem, size, INVALID_VALUE, size) != EOK) {
if (memset_s(mem, size, INVALID_VALUE, size) != EOK) { // LOCV_EXCL_BR_LINE
LOG_FULL(FATAL) << "memset_s failed";
UNREACHABLE();
}

View File

@ -170,7 +170,7 @@ void ParallelEvacuator::EvacuateRegion(TlabAllocator *allocator, Region *region,
}
LOG_ECMA_IF(address == 0, FATAL) << "Evacuate object failed:" << size;
if (memcpy_s(ToVoidPtr(address), size, ToVoidPtr(ToUintPtr(mem)), size) != EOK) {
if (memcpy_s(ToVoidPtr(address), size, ToVoidPtr(ToUintPtr(mem)), size) != EOK) { // LOCV_EXCL_BR_LINE
LOG_FULL(FATAL) << "memcpy_s failed";
}
if (inHeapProfiler) {
@ -402,7 +402,7 @@ void ParallelEvacuator::UpdateWeakReferenceOpt()
}
return header;
}
} else {
} else { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "WeakRootVisitor: not support gcType yet";
UNREACHABLE();
}

View File

@ -58,7 +58,7 @@ uintptr_t SharedSparseSpace::AllocateWithoutGC(JSThread *thread, size_t size)
uintptr_t SharedSparseSpace::Allocate(JSThread *thread, size_t size, bool allowGC)
{
#if ECMASCRIPT_ENABLE_THREAD_STATE_CHECK
if (UNLIKELY(!thread->IsInRunningStateOrProfiling())) {
if (UNLIKELY(!thread->IsInRunningStateOrProfiling())) { // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "Allocate must be in jsthread running state";
UNREACHABLE();
}
@ -108,7 +108,7 @@ uintptr_t SharedSparseSpace::TryAllocateAndExpand(JSThread *thread, size_t size,
uintptr_t SharedSparseSpace::AllocateNoGCAndExpand(JSThread *thread, size_t size)
{
#if ECMASCRIPT_ENABLE_THREAD_STATE_CHECK
if (UNLIKELY(!thread->IsInRunningStateOrProfiling())) {
if (UNLIKELY(!thread->IsInRunningStateOrProfiling())) { // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "Allocate must be in jsthread running state";
UNREACHABLE();
}
@ -149,7 +149,7 @@ bool SharedSparseSpace::Expand(JSThread *thread)
return false;
}
Region *region = heapRegionAllocator_->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE, thread, sHeap_);
if (region == nullptr) {
if (region == nullptr) { // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "SharedSparseSpace::Expand:region is nullptr";
}
AddRegion(region);
@ -160,7 +160,7 @@ bool SharedSparseSpace::Expand(JSThread *thread)
Region *SharedSparseSpace::AllocateDeserializeRegion(JSThread *thread)
{
Region *region = heapRegionAllocator_->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE, thread, sHeap_);
if (region == nullptr) {
if (region == nullptr) { // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "SharedSparseSpace::AllocateDeserializeRegion:region is nullptr";
}
return region;
@ -461,7 +461,7 @@ SharedLocalSpace::SharedLocalSpace(SharedHeap *heap, size_t initialCapacity, siz
bool SharedLocalSpace::AddRegionToList(Region *region)
{
if (committedSize_ >= maximumCapacity_) {
if (committedSize_ >= maximumCapacity_) { // LOCV_EXCL_BR_LINE
LOG_ECMA_MEM(FATAL) << "AddRegionTotList::Committed size " << committedSize_ << " of local space is too big.";
return false;
}
@ -517,7 +517,7 @@ bool SharedReadOnlySpace::Expand(JSThread *thread)
currentRegion->SetHighWaterMark(top);
}
Region *region = heapRegionAllocator_->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE, thread, heap_);
if (region == nullptr) {
if (region == nullptr) { // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "SharedReadOnlySpace::Expand:region is nullptr";
}
allocator_.Reset(region->GetBegin(), region->GetEnd());
@ -528,7 +528,7 @@ bool SharedReadOnlySpace::Expand(JSThread *thread)
uintptr_t SharedReadOnlySpace::Allocate(JSThread *thread, size_t size)
{
#if ECMASCRIPT_ENABLE_THREAD_STATE_CHECK
if (UNLIKELY(!thread->IsInRunningStateOrProfiling())) {
if (UNLIKELY(!thread->IsInRunningStateOrProfiling())) { // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "Allocate must be in jsthread running state";
UNREACHABLE();
}
@ -589,7 +589,7 @@ SharedHugeObjectSpace::SharedHugeObjectSpace(BaseHeap *heap, HeapRegionAllocator
uintptr_t SharedHugeObjectSpace::Allocate(JSThread *thread, size_t objectSize, AllocateEventType allocType)
{
#if ECMASCRIPT_ENABLE_THREAD_STATE_CHECK
if (UNLIKELY(!thread->IsInRunningStateOrProfiling())) {
if (UNLIKELY(!thread->IsInRunningStateOrProfiling())) { // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "Allocate must be in jsthread running state";
UNREACHABLE();
}
@ -607,7 +607,7 @@ uintptr_t SharedHugeObjectSpace::Allocate(JSThread *thread, size_t objectSize, A
return 0;
}
Region *region = heapRegionAllocator_->AllocateAlignedRegion(this, alignedSize, thread, heap_);
if (region == nullptr) {
if (region == nullptr) { // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "SharedHugeObjectSpace::Allocate:region is nullptr";
}
AddRegion(region);

View File

@ -52,7 +52,7 @@ void SparseSpace::ResetTopPointer(uintptr_t top)
uintptr_t SparseSpace::Allocate(size_t size, bool allowGC)
{
#if ECMASCRIPT_ENABLE_THREAD_STATE_CHECK
if (UNLIKELY(!localHeap_->GetJSThread()->IsInRunningStateOrProfiling())) {
if (UNLIKELY(!localHeap_->GetJSThread()->IsInRunningStateOrProfiling())) { // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "Allocate must be in jsthread running state";
UNREACHABLE();
}
@ -117,7 +117,7 @@ void SparseSpace::PrepareSweeping()
EnumerateRegions([this](Region *current) {
if (!current->InCollectSet()) {
if (UNLIKELY(localHeap_->ShouldVerifyHeap() &&
current->IsGCFlagSet(RegionGCFlags::HAS_BEEN_SWEPT))) {
current->IsGCFlagSet(RegionGCFlags::HAS_BEEN_SWEPT))) { // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "Region should not be swept before PrepareSweeping: " << current;
}
IncreaseLiveObjectSize(current->AliveObject());
@ -547,7 +547,7 @@ LocalSpace::LocalSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacit
bool LocalSpace::AddRegionToList(Region *region)
{
if (committedSize_ >= maximumCapacity_) {
if (committedSize_ >= maximumCapacity_) { // LOCV_EXCL_BR_LINE
LOG_ECMA_MEM(FATAL) << "AddRegionTotList::Committed size " << committedSize_ << " of local space is too big.";
return false;
}
@ -698,7 +698,7 @@ uintptr_t MachineCodeSpace::Allocate(size_t size, bool allowGC)
uintptr_t MachineCodeSpace::Allocate(size_t size, MachineCodeDesc *desc, bool allowGC)
{
#if ECMASCRIPT_ENABLE_THREAD_STATE_CHECK
if (UNLIKELY(!localHeap_->GetJSThread()->IsInRunningStateOrProfiling())) {
if (UNLIKELY(!localHeap_->GetJSThread()->IsInRunningStateOrProfiling())) { // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "Allocate must be in jsthread running state";
UNREACHABLE();
}

View File

@ -68,17 +68,17 @@ void VerifyObjectVisitor::VerifyInactiveSemiSpaceMarkedObject(const BaseHeap *he
{
TaggedObject *object = reinterpret_cast<TaggedObject*>(addr);
Region *objectRegion = Region::ObjectAddressToRange(object);
if (!objectRegion->InInactiveSemiSpace()) {
if (!objectRegion->InInactiveSemiSpace()) { // LOCV_EXCL_BR_LINE
LogErrorForObj(heap, "Verify InactiveSemiSpaceMarkedObject: Object is not in InactiveSemiSpace.", object);
} else {
} else { // LOCV_EXCL_BR_LINE
MarkWord word(object);
if (!word.IsForwardingAddress()) {
if (!word.IsForwardingAddress()) { // LOCV_EXCL_BR_LINE
LogErrorForObj(heap, "Verify InactiveSemiSpaceMarkedObject: not forwarding address.", object);
} else {
ObjectSlot slot(ToUintPtr(object));
TaggedObject *value = word.ToForwardingAddress();
Region *valueRegion = Region::ObjectAddressToRange(value);
if (valueRegion->InInactiveSemiSpace()) {
if (valueRegion->InInactiveSemiSpace()) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap, "Verify InactiveSemiSpaceMarkedObject: forwarding address, "
"but InactiveSemiSpace(FromSpace) Object.", object, slot, value);
}
@ -116,11 +116,11 @@ void VerifyObjectVisitor::VerifyObjectSlotLegal(ObjectSlot slot, TaggedObject *o
{
JSTaggedValue value(slot.GetTaggedType());
if (value.IsWeak()) {
if (ToUintPtr(value.GetTaggedWeakRef()) < INVALID_THRESHOLD) {
if (ToUintPtr(value.GetTaggedWeakRef()) < INVALID_THRESHOLD) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Heap verify detected an invalid value.",
object, slot, value.GetTaggedWeakRef());
}
if (!heap_->IsAlive(value.GetTaggedWeakRef())) {
if (!heap_->IsAlive(value.GetTaggedWeakRef())) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Heap verify detected a dead weak object.",
object, slot, value.GetTaggedWeakRef());
++(*failCount_);
@ -135,11 +135,11 @@ void VerifyObjectVisitor::VerifyHeapObjectSlotLegal(ObjectSlot slot,
TaggedObject *object) const
{
ASSERT(slotValue.IsHeapObject());
if (ToUintPtr(slotValue.GetTaggedObject()) < INVALID_THRESHOLD) {
if (ToUintPtr(slotValue.GetTaggedObject()) < INVALID_THRESHOLD) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Heap verify detected an invalid value.",
object, slot, slotValue.GetTaggedObject());
}
if (!heap_->IsAlive(slotValue.GetTaggedObject())) {
if (!heap_->IsAlive(slotValue.GetTaggedObject())) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Heap verify detected a dead object.",
object, slot, slotValue.GetTaggedObject());
++(*failCount_);
@ -176,7 +176,7 @@ void VerifyObjectVisitor::VerifyHeapObjectSlotLegal(ObjectSlot slot,
case VerifyKind::VERIFY_POST_SHARED_GC:
VerifySharedObjectReference(object, slot, slotValue.GetTaggedObject());
break;
default:
default: // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "unknown verify kind:" << static_cast<size_t>(verifyKind_);
UNREACHABLE();
}
@ -189,35 +189,36 @@ void VerifyObjectVisitor::VerifyMarkEden(TaggedObject *object, ObjectSlot slot,
JSTaggedValue value1(object);
JSTaggedValue value2(value);
if (objectRegion->InGeneralOldSpace() && valueRegion->InEdenSpace()) {
if (!objectRegion->TestOldToNew(slot.SlotAddress())) {
if (!objectRegion->TestOldToNew(slot.SlotAddress())) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Verify MarkEden: Old object, slot miss old_to_new bit.", object, slot, value);
} else if (!valueRegion->Test(value)) {
} else if (!valueRegion->Test(value)) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Verify MarkEden: Old object, slot has old_to_new bit, miss gc_mark bit.",
object, slot, value);
}
}
if (objectRegion->InYoungSpace() && valueRegion->InEdenSpace()) {
if (!objectRegion->TestNewToEden(slot.SlotAddress())) {
if (!objectRegion->TestNewToEden(slot.SlotAddress())) { // LOCV_EXCL_BR_LINE
value1.D();
value2.D();
LogErrorForObjSlot(heap_, "Verify MarkEden: Young object, slot miss new_to_eden bit.", object, slot, value);
} else if (!valueRegion->Test(value)) {
} else if (!valueRegion->Test(value)) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Verify MarkEden: Young object, slot has new_to_eden bit, miss gc_mark bit.",
object, slot, value);
}
}
if (objectRegion->Test(object)) {
if (!objectRegion->InEdenSpace() && !objectRegion->InAppSpawnSpace() && !objectRegion->InReadOnlySpace()) {
if (!objectRegion->InEdenSpace() && !objectRegion->InAppSpawnSpace()
&& !objectRegion->InReadOnlySpace()) { // LOCV_EXCL_BR_LINE
LogErrorForObj(heap_, "Verify MarkYoung: Marked object, NOT in Eden Space", object);
}
if (valueRegion->InEdenSpace() && !valueRegion->Test(value)) {
if (valueRegion->InEdenSpace() && !valueRegion->Test(value)) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Verify MarkEden: Marked object, slot in EdenSpace, miss gc_mark bit.",
object, slot, value);
}
if (valueRegion->Test(value) && !(valueRegion->InEdenSpace() || valueRegion->InAppSpawnSpace() ||
valueRegion->InReadOnlySpace() || valueRegion->InSharedHeap())) {
if (valueRegion->Test(value) && !(valueRegion->InEdenSpace() || valueRegion->InAppSpawnSpace()
|| valueRegion->InReadOnlySpace() || valueRegion->InSharedHeap())) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Verify MarkEden: Marked object, slot marked, but NOT in Eden Space.",
object, slot, value);
}
@ -231,31 +232,31 @@ void VerifyObjectVisitor::VerifyMarkYoung(TaggedObject *object, ObjectSlot slot,
Region *valueRegion = Region::ObjectAddressToRange(value);
ASSERT(!objectRegion->InSharedHeap());
if (objectRegion->InGeneralOldSpace() && valueRegion->InGeneralNewSpace()) {
if (!objectRegion->TestOldToNew(slot.SlotAddress())) {
if (!objectRegion->TestOldToNew(slot.SlotAddress())) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Verify MarkYoung: Old object, slot miss old_to_new bit.", object, slot, value);
} else if (!valueRegion->Test(value)) {
} else if (!valueRegion->Test(value)) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Verify MarkYoung: Old object, slot has old_to_new bit, miss gc_mark bit.",
object, slot, value);
}
}
if (!objectRegion->InSharedHeap() && valueRegion->InSharedSweepableSpace()) {
if (!objectRegion->TestLocalToShare(slot.SlotAddress())) {
if (!objectRegion->TestLocalToShare(slot.SlotAddress())) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Verify MarkYoung: Local object, slot local_to_share bit = 0, "
"but SharedHeap object.", object, slot, value);
}
}
if (objectRegion->Test(object)) {
if (!objectRegion->InGeneralNewSpace() && !objectRegion->InAppSpawnSpace() &&
!objectRegion->InReadOnlySpace()) {
!objectRegion->InReadOnlySpace()) { // LOCV_EXCL_BR_LINE
LogErrorForObj(heap_, "Verify MarkYoung: Marked object, NOT in Young/AppSpawn/ReadOnly Space", object);
}
if (valueRegion->InGeneralNewSpace() && !valueRegion->Test(value)) {
if (valueRegion->InGeneralNewSpace() && !valueRegion->Test(value)) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Verify MarkYoung: Marked object, slot in YoungSpace, miss gc_mark bit.",
object, slot, value);
}
if (valueRegion->Test(value) &&
!(valueRegion->InYoungSpace() || valueRegion->InAppSpawnSpace() || valueRegion->InReadOnlySpace() ||
valueRegion->InSharedHeap() || valueRegion->InEdenSpace())) {
valueRegion->InSharedHeap() || valueRegion->InEdenSpace())) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Verify MarkYoung: Marked object, slot marked, but NOT in "
"Young/AppSpawn/ReadOnly Space.", object, slot, value);
}
@ -267,8 +268,8 @@ void VerifyObjectVisitor::VerifyEvacuateEden(TaggedObject *object, ObjectSlot sl
Region *objectRegion = Region::ObjectAddressToRange(object);
Region *valueRegion = Region::ObjectAddressToRange(value);
if (objectRegion->InGeneralOldSpace()) {
if (objectRegion->TestOldToNew(slot.SlotAddress())) {
if (!valueRegion->InActiveSemiSpace()) {
if (objectRegion->TestOldToNew(slot.SlotAddress())) { // LOCV_EXCL_BR_LINE
if (!valueRegion->InActiveSemiSpace()) { // LOCV_EXCL_BR_LINE
if (valueRegion->InEdenSpace()) {
LogErrorForObjSlot(heap_, "Verify EvacuateEden: Old object, slot old_to_new bit = 1, "
"but in EdenSpace object.", object, slot, value);
@ -276,15 +277,15 @@ void VerifyObjectVisitor::VerifyEvacuateEden(TaggedObject *object, ObjectSlot sl
LogErrorForObjSlot(heap_, "Verify EvacuateEden: Old object, slot old_to_new bit = 1, "
"but NOT ActiveSpace(ToSpace) object.", object, slot, value);
}
} else {
if (valueRegion->InGeneralNewSpace()) {
} else { // LOCV_EXCL_BR_LINE
if (valueRegion->InGeneralNewSpace()) { // LOCV_EXCL_BR_LINE
LogErrorForObjSlot(heap_, "Verify EvacuateEden: Old object, slot old_to_new bit = 0, "
"but YoungSpace object.", object, slot, value);
}
}
}
if (objectRegion->InYoungSpace()) {
if (objectRegion->TestNewToEden(slot.SlotAddress())) {
if (objectRegion->TestNewToEden(slot.SlotAddress())) { // LOCV_EXCL_BR_LINE
if (!valueRegion->InEdenSpace()) {
LogErrorForObjSlot(heap_, "Verify EvacuateEden: Young object, slot young_to_eden bit = 1, "
"but NOT Eden object.", object, slot, value);
@ -292,7 +293,7 @@ void VerifyObjectVisitor::VerifyEvacuateEden(TaggedObject *object, ObjectSlot sl
LogErrorForObjSlot(heap_, "Verify EvacuateEden: Young object, slot young_to_eden bit = 1, "
"but Eden object.", object, slot, value);
}
} else {
} else { // LOCV_EXCL_BR_LINE
if (valueRegion->InEdenSpace()) {
LogErrorForObjSlot(heap_, "Verify EvacuateEden: Young object, slot young_to_eden bit = 0, "
"but Eden object.", object, slot, value);
@ -306,7 +307,7 @@ void VerifyObjectVisitor::VerifyEvacuateYoung(TaggedObject *object, ObjectSlot s
Region *objectRegion = Region::ObjectAddressToRange(object);
Region *valueRegion = Region::ObjectAddressToRange(value);
if (objectRegion->InGeneralOldSpace()) {
if (objectRegion->InGeneralOldSpace()) { // LOCV_EXCL_BR_LINE
if (objectRegion->TestOldToNew(slot.SlotAddress())) {
if (!valueRegion->InActiveSemiSpace()) {
if (valueRegion->InEdenSpace()) {
@ -323,13 +324,13 @@ void VerifyObjectVisitor::VerifyEvacuateYoung(TaggedObject *object, ObjectSlot s
}
}
}
if (!objectRegion->InSharedHeap() && valueRegion->InSharedSweepableSpace()) {
if (!objectRegion->InSharedHeap() && valueRegion->InSharedSweepableSpace()) { // LOCV_EXCL_BR_LINE
if (!objectRegion->TestLocalToShare(slot.SlotAddress())) {
LogErrorForObjSlot(heap_, "Verify EvacuateYoung: Local object, slot local_to_share bit = 0, "
"but SharedHeap object.", object, slot, value);
}
}
if (objectRegion->InActiveSemiSpace()) {
if (objectRegion->InActiveSemiSpace()) { // LOCV_EXCL_BR_LINE
if (valueRegion->InInactiveSemiSpace()) {
LogErrorForObjSlot(heap_, "Verify EvacuateYoung: ActiveSpace object, slot in InactiveSpace(FromSpace).",
object, slot, value);
@ -344,17 +345,17 @@ void VerifyObjectVisitor::VerifyMarkFull(TaggedObject *object, ObjectSlot slot,
{
Region *objectRegion = Region::ObjectAddressToRange(object);
Region *valueRegion = Region::ObjectAddressToRange(value);
if (objectRegion->InGeneralOldSpace() && valueRegion->InGeneralNewSpace()) {
if (objectRegion->InGeneralOldSpace() && valueRegion->InGeneralNewSpace()) { // LOCV_EXCL_BR_LINE
if (!objectRegion->TestOldToNew(slot.SlotAddress())) {
LogErrorForObjSlot(heap_, "Verify MarkFull: Old object, slot miss old_to_new bit.", object, slot, value);
}
}
if (objectRegion->Test(object)) {
if (objectRegion->Test(object)) { // LOCV_EXCL_BR_LINE
if (!valueRegion->InSharedHeap() && !valueRegion->Test(value)) {
LogErrorForObjSlot(heap_, "Verify MarkFull: Marked object, slot miss gc_mark bit.", object, slot, value);
}
}
if (!objectRegion->InSharedHeap() && valueRegion->InSharedSweepableSpace()) {
if (!objectRegion->InSharedHeap() && valueRegion->InSharedSweepableSpace()) { // LOCV_EXCL_BR_LINE
if (!objectRegion->TestLocalToShare(slot.SlotAddress())) {
LogErrorForObjSlot(heap_, "Verify VerifyMarkFull: Local object, slot local_to_share bit = 0, "
"but SharedHeap object.", object, slot, value);
@ -380,12 +381,12 @@ void VerifyObjectVisitor::VerifySharedObjectReference(TaggedObject *object, Obje
{
Region *objectRegion = Region::ObjectAddressToRange(object);
Region *valueRegion = Region::ObjectAddressToRange(value);
if (objectRegion->InSharedHeap()) {
if (objectRegion->InSharedHeap()) { // LOCV_EXCL_BR_LINE
if (!valueRegion->InSharedHeap()) {
LogErrorForObjSlot(heap_, "Verify SharedObjectReference: Shared object references a local object",
object, slot, value);
}
} else if (valueRegion->InSharedSweepableSpace()) {
} else if (valueRegion->InSharedSweepableSpace()) { // LOCV_EXCL_BR_LINE
if (!objectRegion->TestLocalToShare(slot.SlotAddress())) {
LogErrorForObjSlot(heap_, "Verify SharedObjectReference: Local object, slot local_to_share bit = 0, "
"but SharedHeap object.", object, slot, value);
@ -397,7 +398,7 @@ void VerifyObjectVisitor::VerifySharedRSetPostFullGC(TaggedObject *object, Objec
{
Region *objectRegion = Region::ObjectAddressToRange(object);
Region *valueRegion = Region::ObjectAddressToRange(value);
if (!objectRegion->InSharedHeap() && valueRegion->InSharedSweepableSpace()) {
if (!objectRegion->InSharedHeap() && valueRegion->InSharedSweepableSpace()) { // LOCV_EXCL_BR_LINE
if (!objectRegion->TestLocalToShare(slot.SlotAddress())) {
LogErrorForObjSlot(heap_, "Verify SharedRSetPostFullGC: Local object, slot local_to_share bit = 0, "
"but SharedHeap object.", object, slot, value);
@ -431,7 +432,7 @@ void Verification::VerifyAll() const
heap_->GetSweeper()->EnsureAllTaskFinished();
size_t result = VerifyRoot();
result += VerifyHeap();
if (result > 0) {
if (result > 0) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "Verify (type=" << static_cast<uint8_t>(verifyKind_)
<< ") corrupted and " << result << " corruptions";
}
@ -536,7 +537,7 @@ void SharedHeapVerification::VerifyAll() const
sHeap_->GetSweeper()->EnsureAllTaskFinished();
size_t result = VerifyRoot();
result += VerifyHeap();
if (result > 0) {
if (result > 0) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "Verify (type=" << static_cast<uint8_t>(verifyKind_)
<< ") corrupted and " << result << " corruptions";
}
@ -553,7 +554,7 @@ void SharedHeapVerification::VerifyMark(bool cm) const
heap->GetSweeper()->EnsureAllTaskFinished();
const_cast<Heap*>(heap)->FillBumpPointerForTlab();
auto localBuffer = const_cast<Heap*>(heap)->GetMarkingObjectLocalBuffer();
if (localBuffer != nullptr) {
if (localBuffer != nullptr) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "verify shared node not null " << cm << ':' << thread;
UNREACHABLE();
}
@ -569,17 +570,17 @@ void SharedHeapVerification::VerifyMark(bool cm) const
if (!valueRegion->InSharedSweepableSpace()) {
return;
}
if (!objectRegion->TestLocalToShare(slot.SlotAddress())) {
if (!objectRegion->TestLocalToShare(slot.SlotAddress())) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "verify shared1 " << cm << ':' << slot.SlotAddress()
<< ' ' << value.GetTaggedObject();
UNREACHABLE();
}
if (!valueRegion->Test(value.GetTaggedObject())) {
if (!valueRegion->Test(value.GetTaggedObject())) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "verify shared2 " << cm << ':' << slot.SlotAddress()
<< ' ' << value.GetTaggedObject();
UNREACHABLE();
}
if (value.GetTaggedObject()->GetClass()->IsFreeObject()) {
if (value.GetTaggedObject()->GetClass()->IsFreeObject()) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "verify shared3 " << cm << ':' << slot.SlotAddress()
<< ' ' << value.GetTaggedObject();
UNREACHABLE();
@ -619,17 +620,18 @@ void SharedHeapVerification::VerifyMark(bool cm) const
return;
}
[[maybe_unused]] Region *valueRegion = Region::ObjectAddressToRange(value.GetTaggedObject());
if (!valueRegion->InSharedHeap()) {
if (!valueRegion->InSharedHeap()) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "verify shared4 " << cm << ':' << slot.SlotAddress()
<< ' ' << value.GetTaggedObject();
UNREACHABLE();
}
if (!valueRegion->InSharedReadOnlySpace() && !valueRegion->Test(value.GetTaggedObject())) {
if (!valueRegion->InSharedReadOnlySpace()
&& !valueRegion->Test(value.GetTaggedObject())) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "verify shared5 " << cm << ':' << slot.SlotAddress()
<< ' ' << value.GetTaggedObject();
UNREACHABLE();
}
if (value.GetTaggedObject()->GetClass()->IsFreeObject()) {
if (value.GetTaggedObject()->GetClass()->IsFreeObject()) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "verify shared6 " << cm << ':' << slot.SlotAddress()
<< ' ' << value.GetTaggedObject();
UNREACHABLE();
@ -680,17 +682,17 @@ void SharedHeapVerification::VerifySweep(bool cm) const
if (!valueRegion->InSharedSweepableSpace()) {
return;
}
if (!objectRegion->TestLocalToShare(slot.SlotAddress())) {
if (!objectRegion->TestLocalToShare(slot.SlotAddress())) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "verify shared7 " << cm << ':' << slot.SlotAddress()
<< ' ' << value.GetTaggedObject();
UNREACHABLE();
}
if (!valueRegion->Test(value.GetTaggedObject())) {
if (!valueRegion->Test(value.GetTaggedObject())) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "verify shared8 " << cm << ':' << slot.SlotAddress()
<< ' ' << value.GetTaggedObject();
UNREACHABLE();
}
if (value.GetTaggedObject()->GetClass()->IsFreeObject()) {
if (value.GetTaggedObject()->GetClass()->IsFreeObject()) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "verify shared9 " << cm << ':' << slot.SlotAddress()
<< ' ' << value.GetTaggedObject();
UNREACHABLE();
@ -722,7 +724,7 @@ void SharedHeapVerification::VerifySweep(bool cm) const
auto jsHclass = obj->GetClass();
auto f = [cm] (ObjectSlot slot, TaggedObject *obj) {
[[maybe_unused]] Region *objectRegion = Region::ObjectAddressToRange(obj);
if (!objectRegion->Test(obj)) {
if (!objectRegion->Test(obj)) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "verify shared10 " << cm << ':' << obj;
UNREACHABLE();
}
@ -731,17 +733,18 @@ void SharedHeapVerification::VerifySweep(bool cm) const
return;
}
[[maybe_unused]] Region *valueRegion = Region::ObjectAddressToRange(value.GetTaggedObject());
if (!valueRegion->InSharedHeap()) {
if (!valueRegion->InSharedHeap()) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "verify shared11 " << cm << ':' << slot.SlotAddress()
<< ' ' << value.GetTaggedObject();
UNREACHABLE();
}
if (!valueRegion->InSharedReadOnlySpace() && !valueRegion->Test(value.GetTaggedObject())) {
if (!valueRegion->InSharedReadOnlySpace()
&& !valueRegion->Test(value.GetTaggedObject())) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "verify shared12 " << cm << ':' << slot.SlotAddress()
<< ' ' << value.GetTaggedObject();
UNREACHABLE();
}
if (value.GetTaggedObject()->GetClass()->IsFreeObject()) {
if (value.GetTaggedObject()->GetClass()->IsFreeObject()) { // LOCV_EXCL_BR_LINE
LOG_GC(FATAL) << "verify shared13 " << cm << ':' << slot.SlotAddress()
<< ' ' << value.GetTaggedObject();
UNREACHABLE();

View File

@ -171,7 +171,7 @@ void WorkManager::Initialize(TriggerGCType gcType, ParallelGCTaskPhase taskPhase
holder.allocator_ = new TlabAllocator(heap_);
}
}
if (initialized_.load(std::memory_order_acquire)) {
if (initialized_.load(std::memory_order_acquire)) { // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
}
@ -211,7 +211,7 @@ void SharedGCWorkManager::Initialize(TriggerGCType gcType, SharedParallelMarkPha
holder.allocator_ = new SharedTlabAllocator(sHeap_);
}
}
if (initialized_.load(std::memory_order_acquire)) {
if (initialized_.load(std::memory_order_acquire)) { // LOCV_EXCL_BR_LINE
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
}

View File

@ -24,7 +24,7 @@ uintptr_t WorkSpaceChunk::NewArea(size_t size)
{
ASSERT(allocator_ != nullptr);
auto area = reinterpret_cast<uintptr_t>(allocator_->AllocateBuffer(size));
if (!area) {
if (!area) { // LOCV_EXCL_BR_LINE
LOG_ECMA_MEM(FATAL) << "OOM WorkSpaceChunk : NewArea area is nullptr";
UNREACHABLE();
}

View File

@ -1428,6 +1428,33 @@ host_unittest_action("EcmaVm_051_Test") {
deps += hiviewdfx_deps
}
host_unittest_action("EcmaVm_052_Test") {
module_out_path = module_output_path
sources = [
# test file
"gc_verify_test.cpp",
]
configs = [
"../../:asm_interp_enable_config",
"../../:ecma_test_config",
"$ark_root/assembler:arkassembler_public_config",
"$ark_root/libpandafile:arkfile_public_config",
]
deps = [
"$ark_third_party_root/icu/icu4c:shared_icui18n",
"$ark_third_party_root/icu/icu4c:shared_icuuc",
"../../:libark_jsruntime_test",
sdk_libc_secshared_dep,
]
# hiviewdfx libraries
external_deps = hiviewdfx_ext_deps
deps += hiviewdfx_deps
}
group("unittest") {
testonly = true
@ -1482,6 +1509,7 @@ group("unittest") {
":EcmaVm_048_Test",
":EcmaVm_050_Test",
":EcmaVm_051_Test",
":EcmaVm_052_Test",
]
}
@ -1539,6 +1567,7 @@ group("host_unittest") {
":EcmaVm_048_TestAction",
":EcmaVm_050_TestAction",
":EcmaVm_051_TestAction",
":EcmaVm_052_TestAction",
]
if (is_mac) {
@ -1592,6 +1621,7 @@ group("host_unittest") {
":EcmaVm_048_TestAction",
":EcmaVm_050_TestAction",
":EcmaVm_051_TestAction",
":EcmaVm_052_TestAction",
]
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecmascript/builtins/builtins_ark_tools.h"
#include "ecmascript/ecma_vm.h"
#include "ecmascript/object_factory-inl.h"
#include "ecmascript/mem/concurrent_marker.h"
#include "ecmascript/tests/ecma_test_common.h"
#include "ecmascript/mem/verification.h"
using namespace panda;
using namespace panda::ecmascript;
//In this test case objects cannot be created frequently, because of the HEAP_VERIFY switch is turned on,
//which is easy to cause the test cases to time out.
namespace panda::test {
class GCTest : public BaseTestWithScope<false> {
public:
void SetUp() override
{
JSRuntimeOptions options;
options.SetEnableEdenGC(true);
options.SetArkProperties(options.GetArkProperties() | ArkProperties::ENABLE_HEAP_VERIFY);
instance = JSNApi::CreateEcmaVM(options);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
auto heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
heap->GetConcurrentMarker()->EnableConcurrentMarking(EnableConcurrentMarkType::ENABLE);
heap->GetSweeper()->EnableConcurrentSweep(EnableConcurrentSweepType::ENABLE);
}
};
HWTEST_F_L0(GCTest, VerificationTest)
{
Heap *heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
auto objectFactory = thread->GetEcmaVM()->GetFactory();
[[maybe_unused]] JSHandle<TaggedArray> array = objectFactory->NewTaggedArray(
1024, JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE);
heap->CollectGarbage(TriggerGCType::FULL_GC);
}
} // namespace panda::test

View File

@ -737,6 +737,11 @@
<option name="push" value="test/test/libark_jsruntime_test.so -> /data/test" src="out"/>
</preparer>
</target>
<target name="EcmaVm_052_Test">
<preparer>
<option name="push" value="test/test/libark_jsruntime_test.so -> /data/test" src="out"/>
</preparer>
</target>
<target name="OhosTest">
<preparer>
<option name="push" value="test/test/libark_jsruntime_test.so -> /data/test" src="out"/>