mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 10:09:54 +00:00
Avoid Sendable's DropFrame
Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IALL34 Signed-off-by: hanweiqi <hanweiqi3@huawei.com>
This commit is contained in:
parent
f87fd7f329
commit
401c33fd0a
@ -1300,6 +1300,11 @@ bool DebuggerApi::CheckPromiseQueueSize(const EcmaVM *ecmaVm)
|
||||
return queueSizeEntry == queueSizeCurrent;
|
||||
}
|
||||
|
||||
bool DebuggerApi::CheckIsSendableMethod(const EcmaVM *ecmaVm)
|
||||
{
|
||||
auto *debuggerMgr = ecmaVm->GetJsDebuggerManager();
|
||||
return debuggerMgr->CheckIsSendableMethod();
|
||||
}
|
||||
bool DebuggerApi::IsMainThread()
|
||||
{
|
||||
return JSThread::IsMainThread();
|
||||
|
@ -197,6 +197,7 @@ public:
|
||||
Global<MapRef> internalObjects);
|
||||
|
||||
static bool CheckPromiseQueueSize(const EcmaVM *ecmaVm);
|
||||
static bool CheckIsSendableMethod(const EcmaVM *ecmaVm);
|
||||
static bool IsMainThread();
|
||||
static void DropLastFrame(const EcmaVM *ecmaVm);
|
||||
};
|
||||
|
@ -72,48 +72,62 @@ std::pair<uint16_t, uint16_t> DropframeManager::ReadStlexvarParams(const uint8_t
|
||||
void DropframeManager::MethodEntry(JSThread *thread, JSHandle<Method> method, JSHandle<JSTaggedValue> envHandle)
|
||||
{
|
||||
std::set<std::pair<uint16_t, uint16_t>> modifiedLexVarPos;
|
||||
NewLexModifyRecordLevel();
|
||||
const JSPandaFile* methodJsPandaFile = method->GetJSPandaFile();
|
||||
panda_file::File::EntityId methodId = method->GetMethodId();
|
||||
PushMethodInfo(std::make_tuple(const_cast<JSPandaFile *>(methodJsPandaFile), methodId));
|
||||
if (!envHandle->IsLexicalEnv()) {
|
||||
if (method->IsSendableMethod()) {
|
||||
PushMethodType(MethodType::SENDABLE_METHOD);
|
||||
return;
|
||||
}
|
||||
NewLexModifyRecordLevel();
|
||||
PushPromiseQueueSizeRecord(thread);
|
||||
if (!envHandle->IsLexicalEnv()) {
|
||||
PushMethodType(MethodType::OTHER_METHOD);
|
||||
return;
|
||||
}
|
||||
PushMethodType(MethodType::NORMAL_METHOD);
|
||||
uint32_t codeSize = method->GetCodeSize();
|
||||
uint16_t newEnvCount = 0;
|
||||
auto bcIns = BytecodeInstruction(method->GetBytecodeArray());
|
||||
auto bcInsLast = bcIns.JumpTo(codeSize);
|
||||
while (bcIns.GetAddress() != bcInsLast.GetAddress()) {
|
||||
BytecodeInstruction::Opcode op = bcIns.GetOpcode();
|
||||
if (IsNewlexenvOpcode(op)) {
|
||||
newEnvCount++;
|
||||
} else if (IsStlexvarOpcode(op)) {
|
||||
std::pair<uint16_t, uint16_t> lexVarPos = ReadStlexvarParams(bcIns.GetAddress(), op);
|
||||
uint16_t level;
|
||||
uint16_t slot;
|
||||
std::tie(level, slot) = lexVarPos;
|
||||
JSTaggedValue env = envHandle.GetTaggedValue();
|
||||
for (uint16_t i = 0; ; i++) {
|
||||
if ((level < newEnvCount || i >= level - newEnvCount) &&
|
||||
slot < LexicalEnv::Cast(env.GetTaggedObject())->GetLength() - LexicalEnv::RESERVED_ENV_LENGTH &&
|
||||
!modifiedLexVarPos.count({i, slot})) {
|
||||
JSTaggedValue value = LexicalEnv::Cast(env.GetTaggedObject())->GetProperties(slot);
|
||||
EmplaceLexModifyRecord(thread, env, slot, value);
|
||||
modifiedLexVarPos.insert({i, slot});
|
||||
}
|
||||
if (i >= level) {
|
||||
break;
|
||||
}
|
||||
JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
|
||||
if (!taggedParentEnv.IsLexicalEnv()) {
|
||||
break;
|
||||
}
|
||||
env = taggedParentEnv;
|
||||
}
|
||||
}
|
||||
AddLexPropertiesToRecord(thread, bcIns, newEnvCount, modifiedLexVarPos, envHandle);
|
||||
bcIns = bcIns.GetNext();
|
||||
}
|
||||
PushPromiseQueueSizeRecord(thread);
|
||||
}
|
||||
|
||||
void DropframeManager::AddLexPropertiesToRecord(JSThread *thread, BytecodeInstruction &bcIns, uint16_t &newEnvCount,
|
||||
std::set<std::pair<uint16_t, uint16_t>> &modifiedLexVarPos, JSHandle<JSTaggedValue> envHandle)
|
||||
{
|
||||
BytecodeInstruction::Opcode op = bcIns.GetOpcode();
|
||||
if (IsNewlexenvOpcode(op)) {
|
||||
newEnvCount++;
|
||||
return;
|
||||
}
|
||||
if (IsStlexvarOpcode(op)) {
|
||||
std::pair<uint16_t, uint16_t> lexVarPos = ReadStlexvarParams(bcIns.GetAddress(), op);
|
||||
uint16_t level;
|
||||
uint16_t slot;
|
||||
std::tie(level, slot) = lexVarPos;
|
||||
JSTaggedValue env = envHandle.GetTaggedValue();
|
||||
for (uint16_t i = 0; ; i++) {
|
||||
if ((level < newEnvCount || i >= level - newEnvCount) &&
|
||||
slot < LexicalEnv::Cast(env.GetTaggedObject())->GetLength() - LexicalEnv::RESERVED_ENV_LENGTH &&
|
||||
!modifiedLexVarPos.count({i, slot})) {
|
||||
JSTaggedValue value = LexicalEnv::Cast(env.GetTaggedObject())->GetProperties(slot);
|
||||
EmplaceLexModifyRecord(thread, env, slot, value);
|
||||
modifiedLexVarPos.insert({i, slot});
|
||||
}
|
||||
if (i >= level) {
|
||||
break;
|
||||
}
|
||||
JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
|
||||
if (!taggedParentEnv.IsLexicalEnv()) {
|
||||
break;
|
||||
}
|
||||
env = taggedParentEnv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DropframeManager::MethodExit(JSThread *thread, [[maybe_unused]] JSHandle<Method> method)
|
||||
@ -124,6 +138,11 @@ void DropframeManager::MethodExit(JSThread *thread, [[maybe_unused]] JSHandle<Me
|
||||
return;
|
||||
}
|
||||
PopMethodInfo();
|
||||
if (CheckIsSendableMethod()) {
|
||||
PopMethodType();
|
||||
return;
|
||||
}
|
||||
PopMethodType();
|
||||
MergeLexModifyRecordOfTopFrame(thread);
|
||||
PopPromiseQueueSizeRecord();
|
||||
}
|
||||
@ -142,6 +161,7 @@ void DropframeManager::DropLastFrame(JSThread *thread)
|
||||
LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot, valueHandle.GetTaggedValue());
|
||||
}
|
||||
PopMethodInfo();
|
||||
PopMethodType();
|
||||
RemoveLexModifyRecordOfTopFrame(thread);
|
||||
PopPromiseQueueSizeRecord();
|
||||
|
||||
@ -226,6 +246,11 @@ void DropframeManager::MergeLexModifyRecordOfTopFrame(JSThread *thread)
|
||||
std::vector<std::tuple<JSHandle<JSTaggedValue>, uint16_t, JSHandle<JSTaggedValue>>> lexModifyRecord;
|
||||
lexModifyRecord = modifiedLexVar_.top();
|
||||
modifiedLexVar_.pop();
|
||||
if (!modifiedLexVar_.empty() && modifiedLexVar_.top().empty()) {
|
||||
modifiedLexVar_.pop();
|
||||
modifiedLexVar_.push(lexModifyRecord);
|
||||
return;
|
||||
}
|
||||
for (const auto &item : lexModifyRecord) {
|
||||
JSHandle<JSTaggedValue> envHandle;
|
||||
uint16_t slot;
|
||||
@ -295,4 +320,22 @@ void DropframeManager::PopMethodInfo()
|
||||
methodInfo_.pop();
|
||||
}
|
||||
}
|
||||
|
||||
void DropframeManager::PushMethodType(MethodType methodType)
|
||||
{
|
||||
methodType_.push(methodType);
|
||||
}
|
||||
|
||||
bool DropframeManager::CheckIsSendableMethod()
|
||||
{
|
||||
ASSERT(!methodType_.empty());
|
||||
return methodType_.top() == MethodType::SENDABLE_METHOD;
|
||||
}
|
||||
|
||||
void DropframeManager::PopMethodType()
|
||||
{
|
||||
if (!methodType_.empty()) {
|
||||
methodType_.pop();
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,12 @@
|
||||
#include "libpandafile/bytecode_instruction.h"
|
||||
|
||||
namespace panda::ecmascript::tooling {
|
||||
enum class MethodType : uint8_t {
|
||||
OTHER_METHOD = 0,
|
||||
NORMAL_METHOD,
|
||||
SENDABLE_METHOD
|
||||
};
|
||||
|
||||
class DropframeManager {
|
||||
public:
|
||||
DropframeManager() = default;
|
||||
@ -33,6 +39,7 @@ public:
|
||||
void MethodExit(JSThread *thread, JSHandle<Method> method);
|
||||
void DropLastFrame(JSThread *thread);
|
||||
uint32_t GetPromiseQueueSizeRecordOfTopFrame();
|
||||
bool CheckIsSendableMethod();
|
||||
private:
|
||||
bool IsNewlexenvOpcode(BytecodeInstruction::Opcode op);
|
||||
bool IsStlexvarOpcode(BytecodeInstruction::Opcode op);
|
||||
@ -52,8 +59,15 @@ private:
|
||||
bool CheckExitMethodInfo(std::tuple<JSPandaFile*, panda_file::File::EntityId> methodInfo);
|
||||
void PopMethodInfo();
|
||||
|
||||
void PushMethodType(MethodType methodType);
|
||||
void PopMethodType();
|
||||
|
||||
void AddLexPropertiesToRecord(JSThread *thread, BytecodeInstruction &bcIns, uint16_t &newEnvCount,
|
||||
std::set<std::pair<uint16_t, uint16_t>> &modifiedLexVarPos, JSHandle<JSTaggedValue> envHandle);
|
||||
|
||||
std::stack<std::vector<std::tuple<JSHandle<JSTaggedValue>, uint16_t, JSHandle<JSTaggedValue>>>> modifiedLexVar_;
|
||||
std::stack<uint32_t> promiseQueueSizeRecord_;
|
||||
std::stack<MethodType> methodType_;
|
||||
std::stack<std::tuple<JSPandaFile*, panda_file::File::EntityId>> methodInfo_;
|
||||
};
|
||||
}
|
||||
|
@ -206,6 +206,11 @@ public:
|
||||
return dropframeManager_.GetPromiseQueueSizeRecordOfTopFrame();
|
||||
}
|
||||
|
||||
bool CheckIsSendableMethod()
|
||||
{
|
||||
return dropframeManager_.CheckIsSendableMethod();
|
||||
}
|
||||
|
||||
void EnableObjectHashDisplay()
|
||||
{
|
||||
isObjHashDisplayEnabled_ = true;
|
||||
|
Loading…
Reference in New Issue
Block a user