14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/compiler/pgo_bc_info.h"
174514f5e3Sopenharmony_ci#include "ecmascript/compiler/bytecodes.h"
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu {
204514f5e3Sopenharmony_civoid PGOBCInfo::Info::Record(const InfoDetail &detail)
214514f5e3Sopenharmony_ci{
224514f5e3Sopenharmony_ci    auto it = methodOffsetToValVec_.find(detail.methodOffset);
234514f5e3Sopenharmony_ci    if (it == methodOffsetToValVec_.end()) {
244514f5e3Sopenharmony_ci        methodOffsetToValVec_[detail.methodOffset] =
254514f5e3Sopenharmony_ci            ValVec { Val { detail.bcIndex, detail.bcOffset, detail.cpIndex} };
264514f5e3Sopenharmony_ci    } else {
274514f5e3Sopenharmony_ci        it->second.emplace_back(Val{ detail.bcIndex, detail.bcOffset, detail.cpIndex });
284514f5e3Sopenharmony_ci    }
294514f5e3Sopenharmony_ci    recordNameToValCount_[detail.recordName]++;
304514f5e3Sopenharmony_ci}
314514f5e3Sopenharmony_ci
324514f5e3Sopenharmony_ciuint32_t PGOBCInfo::Info::GetPGOExtendGTCount(const CString &recordName) const
334514f5e3Sopenharmony_ci{
344514f5e3Sopenharmony_ci    auto it = recordNameToValCount_.find(recordName);
354514f5e3Sopenharmony_ci    if (it != recordNameToValCount_.end()) {
364514f5e3Sopenharmony_ci        return it->second;
374514f5e3Sopenharmony_ci    }
384514f5e3Sopenharmony_ci    return 0;
394514f5e3Sopenharmony_ci}
404514f5e3Sopenharmony_ci
414514f5e3Sopenharmony_ciconst PGOBCInfo::Info& PGOBCInfo::GetInfo(Type type) const
424514f5e3Sopenharmony_ci{
434514f5e3Sopenharmony_ci    ASSERT(Type::TYPE_FIRST <= type && type <= Type::TYPE_LAST);
444514f5e3Sopenharmony_ci    return infos_[type];
454514f5e3Sopenharmony_ci}
464514f5e3Sopenharmony_ci
474514f5e3Sopenharmony_ciuint32_t PGOBCInfo::GetPGOExtendGTCount(const CString &recordName) const
484514f5e3Sopenharmony_ci{
494514f5e3Sopenharmony_ci    uint32_t count = 0;
504514f5e3Sopenharmony_ci    for (const Info &info : infos_) {
514514f5e3Sopenharmony_ci        count += info.GetPGOExtendGTCount(recordName);
524514f5e3Sopenharmony_ci    }
534514f5e3Sopenharmony_ci    return count;
544514f5e3Sopenharmony_ci}
554514f5e3Sopenharmony_ci
564514f5e3Sopenharmony_civoid PGOBCInfo::Record(const InfoDetail &detail, Type type)
574514f5e3Sopenharmony_ci{
584514f5e3Sopenharmony_ci    ASSERT(Type::TYPE_FIRST <= type && type <= Type::TYPE_LAST);
594514f5e3Sopenharmony_ci    Info &info = infos_[type];
604514f5e3Sopenharmony_ci    info.Record(detail);
614514f5e3Sopenharmony_ci}
624514f5e3Sopenharmony_ci
634514f5e3Sopenharmony_civoid PGOBCInfo::Record(const BytecodeInstruction &bcIns, int32_t bcIndex,
644514f5e3Sopenharmony_ci                       const CString &recordName, const MethodLiteral *method)
654514f5e3Sopenharmony_ci{
664514f5e3Sopenharmony_ci    BytecodeInstruction::Opcode opcode = static_cast<BytecodeInstruction::Opcode>(bcIns.GetOpcode());
674514f5e3Sopenharmony_ci    uint32_t methodOffset = method->GetMethodId().GetOffset();
684514f5e3Sopenharmony_ci    uint32_t bcOffset = bcIns.GetAddress() - method->GetBytecodeArray();
694514f5e3Sopenharmony_ci    if (Bytecodes::IsCreateObjectWithBufferOp(opcode)) {
704514f5e3Sopenharmony_ci        auto cpIndex = bcIns.GetId().AsRawValue();
714514f5e3Sopenharmony_ci        Record(InfoDetail {recordName, methodOffset, bcIndex, bcOffset, cpIndex}, Type::OBJ_LITERAL);
724514f5e3Sopenharmony_ci    } else if (Bytecodes::IsCreateArrayWithBufferOp(opcode)) {
734514f5e3Sopenharmony_ci        auto cpIndex = bcIns.GetId().AsRawValue();
744514f5e3Sopenharmony_ci        Record(InfoDetail {recordName, methodOffset, bcIndex, bcOffset, cpIndex}, Type::ARRAY_LITERAL);
754514f5e3Sopenharmony_ci    } else if (Bytecodes::IsCreateEmptyArrayOp(opcode)) {
764514f5e3Sopenharmony_ci        Record(InfoDetail {recordName, methodOffset, bcIndex, bcOffset, 0}, Type::EMPTY_ARRAY);
774514f5e3Sopenharmony_ci    } else if (Bytecodes::IsCallOp(opcode)) {
784514f5e3Sopenharmony_ci        Record(InfoDetail {recordName, methodOffset, bcIndex, bcOffset, 0}, Type::CALL_TARGET);
794514f5e3Sopenharmony_ci    } else if (Bytecodes::IsDefineClassWithBufferOp(opcode)) {
804514f5e3Sopenharmony_ci        Record(InfoDetail {recordName, methodOffset, bcIndex, bcOffset, 0}, Type::CLASS);
814514f5e3Sopenharmony_ci    } else if (Bytecodes::IsDefineFunc(opcode)) {
824514f5e3Sopenharmony_ci        Record(InfoDetail {recordName, methodOffset, bcIndex, bcOffset, 0}, Type::FUNCTION);
834514f5e3Sopenharmony_ci    }
844514f5e3Sopenharmony_ci}
854514f5e3Sopenharmony_ci}  // namespace panda::ecmascript
86