* Copyright (c) 2026 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.
*/
#ifndef ECMASCRIPT_ARKSTEED_SAFEPOINT_TABLE_H
#define ECMASCRIPT_ARKSTEED_SAFEPOINT_TABLE_H
#include <vector>
#include "ecmascript/common.h"
namespace panda::ecmascript::arksteed {
#pragma pack(1)
struct ArkSteedSafepointHeader {
uint32_t numEntries;
uint32_t numTaggedSlots;
uint32_t numUntaggedSlots;
uint32_t reserved;
};
struct ArkSteedSafepointEntry {
uint32_t pcOffset;
uint16_t numExtraSpillSlots;
uint16_t taggedRegisterIndexes;
};
#pragma pack()
static_assert(sizeof(ArkSteedSafepointHeader) == 16, "Header must be 16 bytes");
static_assert(sizeof(ArkSteedSafepointEntry) == 8, "Entry must be 8 bytes");
class PUBLIC_API ArkSteedSafepointTableBuilder {
public:
class Safepoint {
public:
void DefineTaggedRegister(int pushedRegIndex)
{
entry_->taggedRegisterIndexes |= static_cast<uint16_t>(1u << pushedRegIndex);
}
void SetNumExtraSpillSlots(int count)
{
entry_->numExtraSpillSlots = static_cast<uint16_t>(count);
}
private:
friend class ArkSteedSafepointTableBuilder;
explicit Safepoint(ArkSteedSafepointEntry *entry) : entry_(entry) {}
ArkSteedSafepointEntry *entry_;
};
Safepoint DefineSafepoint(uint32_t pcOffset);
void SetFrameSlots(uint32_t tagged, uint32_t untagged);
size_t GetTableSize() const;
void Emit(uint8_t *buffer) const;
uint8_t *EmitToNewBuffer() const;
uint32_t GetNumEntries() const
{
return static_cast<uint32_t>(entries_.size());
}
private:
uint32_t numTaggedSlots_ = 0;
uint32_t numUntaggedSlots_ = 0;
std::vector<ArkSteedSafepointEntry> entries_;
};
class ArkSteedSafepointTable {
public:
ArkSteedSafepointTable(const uint8_t *data, size_t size);
uint32_t GetNumTaggedSlots() const
{
return header_->numTaggedSlots;
}
uint32_t GetNumUntaggedSlots() const
{
return header_->numUntaggedSlots;
}
uint32_t GetNumEntries() const
{
return header_->numEntries;
}
const ArkSteedSafepointEntry *FindEntry(uint32_t pcOffset) const;
bool IsValid() const
{
return header_ != nullptr;
}
private:
const ArkSteedSafepointHeader *header_ = nullptr;
const ArkSteedSafepointEntry *entries_ = nullptr;
};
}
#endif