* 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.
*/
#ifndef ECMASCRIPT_COMPILER_BARRIER_STUB_BUILDER_H
#define ECMASCRIPT_COMPILER_BARRIER_STUB_BUILDER_H
#include "ecmascript/compiler/stub_builder.h"
namespace panda::ecmascript::kungfu {
class BarrierStubBuilder : public StubBuilder {
public:
BarrierStubBuilder(StubBuilder *parent, GateRef glue, GateRef obj, GateRef startAddr, GateRef slotCount)
: StubBuilder(parent),
glue_(glue),
dstObj_(obj),
dstAddr_(startAddr),
slotCount_(slotCount),
objectRegion_(ObjectAddressToRange(obj)) {}
~BarrierStubBuilder() override = default;
NO_MOVE_SEMANTIC(BarrierStubBuilder);
NO_COPY_SEMANTIC(BarrierStubBuilder);
void GenerateCircuit() override {}
void DoMoveBarrierCrossRegion(GateRef srcAddr, GateRef srcRegion);
void DoBatchBarrier();
void DoMoveBarrierInRegion(GateRef srcAddr);
void DoReverseBarrier();
private:
enum BitSetSelect {
LocalToShared = 0b1,
OldToNew = 0b10,
};
enum RegionKind {
InSameRegion,
CrossRegion,
};
GateRef GetBitSetDataAddr(GateRef objectRegion, GateRef loadOffset, int32_t createFunID);
void HandleMark();
void DoBatchBarrierInternal();
void BarrierBatchBitSet(uint8_t select);
void FlushBatchBitSet(uint8_t bitSetSelect, GateRef quadIdx,
Variable &localToShareBitSetVar, Variable &oldToNewBitSetVar, Label *next);
GateRef IsLocalToShareSwappedFast(GateRef region);
GateRef IsLocalToShareSwapped(GateRef region);
GateRef IsOldToNewSwapped(GateRef region);
void BitSetRangeMove(GateRef srcBitSet, GateRef dstBitSet, GateRef srcStart, GateRef dstStart, GateRef length);
void BitSetRangeMoveForward(GateRef srcBitSet, GateRef dstBitSet, GateRef srcStart, GateRef dstStart,
GateRef length);
void BitSetRangeMoveBackward(GateRef srcBitSet, GateRef dstBitSet, GateRef srcStart, GateRef dstStart,
GateRef length);
void DoReverseBarrierInternal();
void BitSetRangeReverse(GateRef bitSet, GateRef startIdx, GateRef length);
void DoMoveBarrierSameRegionKind(GateRef srcAddr, GateRef srcRegion, RegionKind regionKind);
const GateRef glue_;
const GateRef dstObj_;
const GateRef dstAddr_;
const GateRef slotCount_;
const GateRef objectRegion_;
static constexpr int64_t BIT_PER_QUAD_MASK = 63;
static constexpr int64_t BIT_PER_QUAD_LOG2 = 6;
static constexpr int64_t BYTE_PER_QUAD_LOG2 = 3;
static constexpr int64_t BYTE_PER_QUAD = 8;
static constexpr int64_t BIT_PER_BYTE_LOG2 = 3;
static constexpr int64_t BIT_PER_QUAD = 64;
static constexpr int64_t ALL_ONE_MASK = -1;
static constexpr size_t FLUSH_RANGE = GCBitset::BIT_PER_WORD * GCBitset::BIT_PER_BYTE;
static constexpr int8_t LOCAL_TO_SHARE_SWAPPED_MASK =
static_cast<int8_t>(RSetSwapFlag::LOCAL_TO_SHARE_SWAPPED_MASK) |
static_cast<int8_t>(RSetSwapFlag::LOCAL_TO_SHARE_COLLECTED_MASK);
static constexpr int8_t OLD_TO_NEW_SWAPPED_MASK = static_cast<int8_t>(RSetSwapFlag::OLD_TO_NEW_SWAPPED_MASK);
};
}
#endif