ArkTools - Collect Scope-Lock Stats

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I9OEBY

Signed-off-by: yaoyuan <yuanyao14@huawei.com>
Change-Id: Iafdcac5b289bcc4f0232bb1b7d04cb017a8a01b9
This commit is contained in:
yaoyuan 2024-05-13 10:40:19 +08:00
parent e729610d81
commit 6a55087701
7 changed files with 226 additions and 0 deletions

View File

@ -33,6 +33,7 @@ namespace panda::ecmascript {
#define ECMASCRIPT_ENABLE_JIT_WARMUP_PROFILER 0
#define ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER 0
#define ECMASCRIPT_ENABLE_ELEMENTSKIND_ALWAY_GENERIC 0
#define ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT 0
#ifndef NDEBUG
#define ECMASCRIPT_ENABLE_INTERPRETER_LOG 1

View File

@ -541,6 +541,34 @@ JSTaggedValue BuiltinsArkTools::TimeInUs([[maybe_unused]] EcmaRuntimeCallInfo *i
ClockScope scope;
return JSTaggedValue(scope.GetCurTime());
}
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
JSTaggedValue BuiltinsArkTools::StartScopeLockStats(EcmaRuntimeCallInfo *info)
{
JSThread *thread = info->GetThread();
auto vm = thread->GetEcmaVM();
vm->StartCollectingScopeLockStats();
LOG_FULL(INFO) << "Start Collecting ArkCompiler Scope-Lock Stats";
return JSTaggedValue::Undefined();
}
JSTaggedValue BuiltinsArkTools::StopScopeLockStats(EcmaRuntimeCallInfo *info)
{
JSThread *thread = info->GetThread();
auto vm = thread->GetEcmaVM();
LOG_FULL(INFO) << "Stop Collecting ArkCompiler Scope-Lock Stats: "
<< " ThreadStateTransition count: " << vm->GetUpdateThreadStateTransCount()
<< " , Entered Scope But NO State Transition count: " << (vm->GetEnterJsiNativeScopeCount() +
vm->GetEnterFastNativeScopeCount() +
vm->GetEnterThreadManagedScopeCount() -
vm->GetUpdateThreadStateTransCount())
<< " , String-Table Lock count: " << vm->GetStringTableLockCount();
vm->ResetScopeLockStats();
vm->StopCollectingScopeLockStats();
return JSTaggedValue::Undefined();
}
#endif
// empty function for regress-xxx test cases
JSTaggedValue BuiltinsArkTools::PrepareFunctionForOptimization([[maybe_unused]] EcmaRuntimeCallInfo *info)
{

View File

@ -128,6 +128,13 @@
V("jitCompileAsync", JitCompileAsync, 1, INVALID) \
V("waitJitCompileFinish", WaitJitCompileFinish, 1, INVALID)
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
#define BUILTIN_ARK_TOOLS_FUNCTIONS_SCOPE_LOCK_STATS(V) \
V("startScopeLockStats", StartScopeLockStats, 0, INVALID) \
V("stopScopeLockStats", StopScopeLockStats, 0, INVALID)
#else
#define BUILTIN_ARK_TOOLS_FUNCTIONS_SCOPE_LOCK_STATS(V) // Nothing
#endif
#ifdef ECMASCRIPT_SUPPORT_CPUPROFILER
#define BUILTIN_ARK_TOOLS_FUNCTIONS_CPUPROFILER(V) \
@ -141,6 +148,7 @@
BUILTIN_ARK_TOOLS_FUNCTIONS_COMMON(V) \
BUILTIN_ARK_TOOLS_FUNCTIONS_CPUPROFILER(V) \
BUILTIN_ARK_TOOLS_FUNCTIONS_REGRESS(V) \
BUILTIN_ARK_TOOLS_FUNCTIONS_SCOPE_LOCK_STATS(V) \
BUILTIN_ARK_TOOLS_FUNCTIONS_JITCOMPILE(V)
namespace panda::ecmascript::builtins {
@ -220,6 +228,12 @@ public:
static JSTaggedValue TimeInUs(EcmaRuntimeCallInfo *info);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
static JSTaggedValue StartScopeLockStats(EcmaRuntimeCallInfo *info);
static JSTaggedValue StopScopeLockStats(EcmaRuntimeCallInfo *info);
#endif
static JSTaggedValue PrepareFunctionForOptimization(EcmaRuntimeCallInfo *info);
static JSTaggedValue OptimizeFunctionOnNextCall(EcmaRuntimeCallInfo *info);

View File

@ -26,8 +26,20 @@ public:
: self_(self)
{
ASSERT(self_ != nullptr);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
auto vm = self_->GetEcmaVM();
bool isCollectingStats = vm->IsCollectingScopeLockStats();
if (isCollectingStats) {
vm->IncreaseEnterThreadManagedScopeCount();
}
#endif
oldState_ = self_->GetState();
if (oldState_ != newState) {
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
if (isCollectingStats) {
vm->IncreaseUpdateThreadStateTransCount();
}
#endif
self_->UpdateState(newState);
}
}

View File

@ -105,6 +105,12 @@ void EcmaStringTable::InternStringThreadUnsafe(EcmaString *string)
void EcmaStringTable::InternEmptyString(JSThread *thread, EcmaString *emptyStr)
{
RuntimeLockHolder locker(thread, mutex_);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
auto vm = thread->GetEcmaVM();
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
InternStringThreadUnsafe(emptyStr);
}
@ -114,6 +120,11 @@ EcmaString *EcmaStringTable::GetOrInternString(EcmaVM *vm, const JSHandle<EcmaSt
auto firstFlat = JSHandle<EcmaString>(vm->GetJSThread(), EcmaStringAccessor::Flatten(vm, firstString));
auto secondFlat = JSHandle<EcmaString>(vm->GetJSThread(), EcmaStringAccessor::Flatten(vm, secondString));
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
std::pair<EcmaString *, uint32_t> result = GetStringThreadUnsafe(firstFlat, secondFlat);
if (result.first != nullptr) {
return result.first;
@ -130,6 +141,11 @@ EcmaString *EcmaStringTable::GetOrInternString(EcmaVM *vm, const uint8_t *utf8Da
bool canBeCompress)
{
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
std::pair<EcmaString *, uint32_t> result = GetStringThreadUnsafe(utf8Data, utf8Len, canBeCompress);
if (result.first != nullptr) {
return result.first;
@ -146,6 +162,11 @@ EcmaString *EcmaStringTable::GetOrInternCompressedSubString(EcmaVM *vm, const JS
uint32_t offset, uint32_t utf8Len)
{
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
auto *utf8Data = EcmaStringAccessor(string).GetDataUtf8() + offset;
std::pair<EcmaString *, uint32_t> result = GetStringThreadUnsafe(utf8Data, utf8Len, true);
if (result.first != nullptr) {
@ -166,6 +187,11 @@ EcmaString *EcmaStringTable::GetOrInternCompressedSubString(EcmaVM *vm, const JS
EcmaString *EcmaStringTable::CreateAndInternStringNonMovable(EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf8Len)
{
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
std::pair<EcmaString *, uint32_t> result = GetStringThreadUnsafe(utf8Data, utf8Len, true);
if (result.first != nullptr) {
return result.first;
@ -184,6 +210,11 @@ EcmaString *EcmaStringTable::CreateAndInternStringReadOnly(EcmaVM *vm, const uin
bool canBeCompress)
{
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
std::pair<EcmaString *, uint32_t> result = GetStringThreadUnsafe(utf8Data, utf8Len, canBeCompress);
if (result.first != nullptr) {
return result.first;
@ -199,6 +230,11 @@ EcmaString *EcmaStringTable::GetOrInternString(EcmaVM *vm, const uint16_t *utf16
bool canBeCompress)
{
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
std::pair<EcmaString *, uint32_t> result = GetStringThreadUnsafe(utf16Data, utf16Len);
if (result.first != nullptr) {
return result.first;
@ -226,6 +262,11 @@ EcmaString *EcmaStringTable::GetOrInternString(EcmaVM *vm, EcmaString *string)
JSHandle<EcmaString> strFlatHandle(thread, strFlat);
// may gc
RuntimeLockHolder locker(thread, mutex_);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
strFlat = *strFlatHandle;
EcmaString *result = GetStringThreadUnsafe(strFlat);
if (result != nullptr) {
@ -258,6 +299,11 @@ EcmaString *EcmaStringTable::GetOrInternStringThreadUnsafe(EcmaVM *vm, EcmaStrin
EcmaString *EcmaStringTable::InsertStringToTable(EcmaVM *vm, const JSHandle<EcmaString> &strHandle)
{
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
auto strFlat = EcmaStringAccessor::Flatten(vm, strHandle, MemSpaceType::SHARED_OLD_SPACE);
InternStringThreadUnsafe(strFlat);
return strFlat;
@ -266,6 +312,12 @@ EcmaString *EcmaStringTable::InsertStringToTable(EcmaVM *vm, const JSHandle<Ecma
EcmaString *EcmaStringTable::TryGetInternString(JSThread *thread, const JSHandle<EcmaString> &string)
{
RuntimeLockHolder locker(thread, mutex_);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
auto vm = thread->GetEcmaVM();
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
return GetStringThreadUnsafe(*string);
}
@ -275,6 +327,11 @@ EcmaString *EcmaStringTable::GetOrInternStringWithSpaceType(EcmaVM *vm, const ui
{
ASSERT(IsSMemSpace(type));
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
std::pair<EcmaString *, uint32_t> result = GetStringThreadUnsafe(utf8Data, utf8Len, canBeCompress);
if (result.first != nullptr) {
return result.first;
@ -299,6 +356,11 @@ EcmaString *EcmaStringTable::GetOrInternStringWithSpaceType(EcmaVM *vm, const ui
ASSERT(IsSMemSpace(type));
type = (type == MemSpaceType::SHARED_NON_MOVABLE) ? type : MemSpaceType::SHARED_OLD_SPACE;
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
EcmaString *str = EcmaStringAccessor::CreateUtf16StringFromUtf8(vm, utf8Data, utf16Len, type);
EcmaString *result = GetStringThreadUnsafe(str);
if (result != nullptr) {
@ -331,6 +393,11 @@ void EcmaStringTable::SweepWeakReference(const WeakRootVisitor &visitor)
void EcmaStringTable::RelocateConstantData(EcmaVM *vm, const JSPandaFile *jsPandaFile)
{
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
auto thread = vm->GetJSThread();
for (auto it = table_.begin(); it != table_.end();) {
auto *object = it->second;
@ -369,6 +436,12 @@ void EcmaStringTable::RelocateConstantData(EcmaVM *vm, const JSPandaFile *jsPand
bool EcmaStringTable::CheckStringTableValidity(JSThread *thread)
{
RuntimeLockHolder locker(thread, mutex_);
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
auto vm = thread->GetEcmaVM();
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
for (auto itemOuter = table_.begin(); itemOuter != table_.end(); ++itemOuter) {
auto outerString = itemOuter->second;
if (!EcmaStringAccessor(outerString).NotTreeString()) {

View File

@ -710,6 +710,82 @@ public:
{
return sharedNativePointerCallbacks_;
}
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
void ResetScopeLockStats()
{
enterThreadManagedScopeCount_ = 0;
enterJsiNativeScopeCount_ = 0;
enterFastNativeScopeCount_ = 0;
updateThreadStateTransCount_ = 0;
stringTableLockCount_ = 0;
}
bool IsCollectingScopeLockStats() const
{
return isCollectingScopeLockStats_;
}
void StartCollectingScopeLockStats()
{
isCollectingScopeLockStats_ = true;
}
void StopCollectingScopeLockStats()
{
isCollectingScopeLockStats_ = false;
}
int GetEnterThreadManagedScopeCount() const
{
return enterThreadManagedScopeCount_;
}
void IncreaseEnterThreadManagedScopeCount()
{
enterThreadManagedScopeCount_++;
}
int GetEnterFastNativeScopeCount() const
{
return enterFastNativeScopeCount_;
}
void IncreaseEnterFastNativeScopeCount()
{
enterFastNativeScopeCount_++;
}
int GetEnterJsiNativeScopeCount() const
{
return enterJsiNativeScopeCount_;
}
void IncreaseEnterJsiNativeScopeCount()
{
enterJsiNativeScopeCount_++;
}
int GetUpdateThreadStateTransCount() const
{
return updateThreadStateTransCount_;
}
void IncreaseUpdateThreadStateTransCount()
{
updateThreadStateTransCount_++;
}
int GetStringTableLockCount() const
{
return stringTableLockCount_;
}
void IncreaseStringTableLockCount()
{
stringTableLockCount_++;
}
#endif
protected:
void PrintJSErrorInfo(const JSHandle<JSTaggedValue> &exceptionInfo) const;
@ -830,6 +906,16 @@ private:
bool isEnableOsr_ {false};
bool isJitCompileVM_ {false};
bool overLimit_ {false};
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
// Stats for Thread-State-Transition and String-Table Locks
bool isCollectingScopeLockStats_ = false;
int enterThreadManagedScopeCount_ = 0;
int enterFastNativeScopeCount_ = 0;
int enterJsiNativeScopeCount_ = 0;
int updateThreadStateTransCount_ = 0;
int stringTableLockCount_ = 0;
#endif
};
} // namespace ecmascript
} // namespace panda

View File

@ -3317,6 +3317,12 @@ JSExecutionScope::~JSExecutionScope()
JsiNativeScope::JsiNativeScope(const EcmaVM *vm)
{
thread_ = vm->GetAssociatedJSThread();
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
if (vm->IsCollectingScopeLockStats()) {
const_cast<EcmaVM*>(vm)->IncreaseEnterJsiNativeScopeCount();
const_cast<EcmaVM*>(vm)->IncreaseUpdateThreadStateTransCount();
}
#endif
oldThreadState_ = static_cast<uint16_t>(thread_->GetState());
thread_->UpdateState(ecmascript::ThreadState::NATIVE);
}
@ -3331,6 +3337,12 @@ JsiNativeScope::~JsiNativeScope()
JsiFastNativeScope::JsiFastNativeScope(const EcmaVM *vm)
{
thread_ = vm->GetAssociatedJSThread();
#if defined(ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT)
if (vm->IsCollectingScopeLockStats()) {
const_cast<EcmaVM*>(vm)->IncreaseEnterFastNativeScopeCount();
const_cast<EcmaVM*>(vm)->IncreaseUpdateThreadStateTransCount();
}
#endif
oldThreadState_ = static_cast<uint16_t>(thread_->GetState());
thread_->UpdateState(ecmascript::ThreadState::RUNNING);
}