Allocate memory to old space base on PGO

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IAGX2J?from=project-issue
Signed-off-by: 刘智杰 <liuzhijie9@huawei.com>
Change-Id: I61169141d9589a6ae01e30f09fe4690ae29a72bb
This commit is contained in:
刘智杰 2024-09-11 14:17:54 +08:00
parent 2a6d50e69b
commit 8b5e15db80
32 changed files with 336 additions and 34 deletions

View File

@ -1434,4 +1434,24 @@ JSTaggedValue BuiltinsArkTools::IterateFrame(EcmaRuntimeCallInfo *info)
return JSTaggedValue::Undefined();
}
JSTaggedValue BuiltinsArkTools::InYoungSpace(EcmaRuntimeCallInfo *info)
{
RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
CHECK(info && info->GetArgsNumber() == 1);
JSHandle<JSTaggedValue> arg = info->GetCallArg(0);
CHECK(arg->IsHeapObject());
Region *region = Region::ObjectAddressToRange(arg->GetTaggedObject());
return JSTaggedValue(region->InYoungSpace());
}
JSTaggedValue BuiltinsArkTools::InOldSpace(EcmaRuntimeCallInfo *info)
{
RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
CHECK(info && info->GetArgsNumber() == 1);
JSHandle<JSTaggedValue> arg = info->GetCallArg(0);
CHECK(arg->IsHeapObject());
Region *region = Region::ObjectAddressToRange(arg->GetTaggedObject());
return JSTaggedValue(region->InOldSpace());
}
} // namespace panda::ecmascript::builtins

View File

@ -129,7 +129,9 @@
V("notifyContextDisposed", NotifyContextDisposed, 0, INVALID) \
V("optimizeObjectForAddingMultipleProperties", OptimizeObjectForAddingMultipleProperties, 2, INVALID) \
V("isBeingInterpreted", IsBeingInterpreted, 0, INVALID) \
V("clearFunctionFeedback", ClearFunctionFeedback, 1, INVALID)
V("clearFunctionFeedback", ClearFunctionFeedback, 1, INVALID) \
V("inYoungSpace", InYoungSpace, 1, INVALID) \
V("inOldSpace", InOldSpace, 1, INVALID)
#define BUILTIN_ARK_TOOLS_FUNCTIONS_JITCOMPILE(V) \
V("jitCompileSync", JitCompileSync, 1, INVALID) \
@ -184,6 +186,8 @@ public:
static JSTaggedValue IsNotHoleProperty(EcmaRuntimeCallInfo *info);
static JSTaggedValue ForcePartialGC(EcmaRuntimeCallInfo *info);
static JSTaggedValue ForceFullGC(EcmaRuntimeCallInfo *info);
static JSTaggedValue HintGC(EcmaRuntimeCallInfo *info);
@ -397,6 +401,9 @@ public:
static JSTaggedValue IterateFrame(EcmaRuntimeCallInfo *info);
static JSTaggedValue InYoungSpace(EcmaRuntimeCallInfo *info);
static JSTaggedValue InOldSpace(EcmaRuntimeCallInfo *info);
static Span<const base::BuiltinFunctionEntry> GetArkToolsFunctions()
{
return Span<const base::BuiltinFunctionEntry>(ARK_TOOLS_FUNCTIONS);

View File

@ -405,6 +405,11 @@ public:
return pgoTypeRecorder_.GetElementsLength(gateAcc_.TryGetPcOffset(gate));
}
RegionSpaceFlag GetRegionSpaceFlag(GateRef gate) const
{
return pgoTypeRecorder_.GetRegionSpaceFlag(gateAcc_.TryGetPcOffset(gate));
}
bool ShouldPGOTypeInfer(GateRef gate) const
{
return jsGatesToByteCode_.find(gate) != jsGatesToByteCode_.end();

View File

@ -389,9 +389,9 @@ public:
}
// **************************** High IR ******************************
GateRef CreateArray(ElementsKind kind, uint32_t arraySize, GateRef elementsLength);
GateRef CreateArray(ElementsKind kind, uint32_t arraySize, GateRef elementsLength, RegionSpaceFlag flag);
GateRef CreateArrayWithBuffer(ElementsKind kind, ArrayMetaDataAccessor::Mode mode, GateRef cpId,
GateRef constPoolIndex);
GateRef constPoolIndex, RegionSpaceFlag flag);
GateRef CreateArguments(ElementsKind kind, CreateArgumentsAccessor::Mode mode, GateRef restIdx);
GateRef Construct(GateRef hirGate, std::vector<GateRef> args);
GateRef CallNew(GateRef hirGate, std::vector<GateRef> args, bool needPushArgv = false);

View File

@ -229,6 +229,15 @@ void GateAccessor::SetElementsKind(GateRef gate, ElementsKind kind)
const_cast<OneParameterMetaData *>(gatePtr->GetOneParameterMetaData())->SetValue(accessor.ToValue());
}
RegionSpaceFlag GateAccessor::GetRegionSpaceFlag(GateRef gate) const
{
ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
Gate *gatePtr = circuit_->LoadGatePtr(gate);
auto array = gatePtr->GetOneParameterMetaData()->GetValue();
return ArrayMetaDataAccessor(array).GetRegionSpaceFlag();
}
uint32_t GateAccessor::GetStringStatus(GateRef gate) const
{
ASSERT(GetOpCode(gate) == OpCode::STRING_ADD);
@ -663,6 +672,25 @@ void GateAccessor::TrySetArrayElementsLength(GateRef gate, uint32_t length)
}
}
RegionSpaceFlag GateAccessor::TryGetRegionSpaceFlag(GateRef gate) const
{
Gate *gatePtr = circuit_->LoadGatePtr(gate);
OpCode op = GetOpCode(gate);
if (op == OpCode::JS_BYTECODE) {
return gatePtr->GetJSBytecodeMetaData()->GetRegionSpaceFlag();
}
return RegionSpaceFlag::IN_YOUNG_SPACE;
}
void GateAccessor::TrySetRegionSpaceFlag(GateRef gate, RegionSpaceFlag flag)
{
Gate *gatePtr = circuit_->LoadGatePtr(gate);
OpCode op = GetOpCode(gate);
if (op == OpCode::JS_BYTECODE) {
const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetRegionSpaceFlag(flag);
}
}
ElementsKind GateAccessor::TryGetElementsKind(GateRef gate) const
{
Gate *gatePtr = circuit_->LoadGatePtr(gate);

View File

@ -396,6 +396,7 @@ public:
void SetStringStatus(GateRef gate, uint32_t type);
ElementsKind GetElementsKind(GateRef gate) const;
void SetElementsKind(GateRef gate, ElementsKind kind);
RegionSpaceFlag GetRegionSpaceFlag(GateRef gate) const;
size_t GetVirtualRegisterIndex(GateRef gate) const;
bool TypedOpIsTypedArray(GateRef gate, TypedOpKind kind) const;
TypedLoadOp GetTypedLoadOp(GateRef gate) const;
@ -435,6 +436,8 @@ public:
void TrySetPGOType(GateRef gate, PGOTypeRef type);
uint32_t TryGetArrayElementsLength(GateRef gate) const;
void TrySetArrayElementsLength(GateRef gate, uint32_t length);
RegionSpaceFlag TryGetRegionSpaceFlag(GateRef gate) const;
void TrySetRegionSpaceFlag(GateRef gate, RegionSpaceFlag length);
ElementsKind TryGetElementsKind(GateRef gate) const;
ElementsKind TryGetArrayElementsKind(GateRef gate) const;
ElementsKind TryGetArrayElementsKindAfterTransition(GateRef gate) const;

View File

@ -512,12 +512,13 @@ GateRef CircuitBuilder::CallNew(GateRef hirGate, std::vector<GateRef> args,
return callGate;
}
GateRef CircuitBuilder::CreateArray(ElementsKind kind, uint32_t arraySize, GateRef elementsLength)
GateRef CircuitBuilder::CreateArray(ElementsKind kind, uint32_t arraySize,
GateRef elementsLength, RegionSpaceFlag flag)
{
auto currentLabel = env_->GetCurrentLabel();
auto currentControl = currentLabel->GetControl();
auto currentDepend = currentLabel->GetDepend();
ArrayMetaDataAccessor accessor(kind, ArrayMetaDataAccessor::Mode::CREATE, arraySize);
ArrayMetaDataAccessor accessor(kind, ArrayMetaDataAccessor::Mode::CREATE, arraySize, flag);
GateRef newGate = GetCircuit()->NewGate(circuit_->CreateArray(accessor.ToValue()), MachineType::I64,
{ currentControl, currentDepend, elementsLength },
GateType::TaggedValue());
@ -527,13 +528,13 @@ GateRef CircuitBuilder::CreateArray(ElementsKind kind, uint32_t arraySize, GateR
}
GateRef CircuitBuilder::CreateArrayWithBuffer(ElementsKind kind, ArrayMetaDataAccessor::Mode mode, GateRef cpId,
GateRef constPoolIndex)
GateRef constPoolIndex, RegionSpaceFlag flag)
{
auto currentLabel = env_->GetCurrentLabel();
auto currentControl = currentLabel->GetControl();
auto currentDepend = currentLabel->GetDepend();
auto frameState = acc_.FindNearestFrameState(currentDepend);
ArrayMetaDataAccessor accessor(kind, mode);
ArrayMetaDataAccessor accessor(kind, mode, 0, flag);
GateRef newGate = GetCircuit()->NewGate(circuit_->CreateArrayWithBuffer(accessor.ToValue()),
MachineType::I64,
{ currentControl, currentDepend, cpId, constPoolIndex, frameState },

View File

@ -141,6 +141,16 @@ public:
return elementsLength_;
}
void SetRegionSpaceFlag(RegionSpaceFlag flag)
{
regionSpaceFlag_ = flag;
}
RegionSpaceFlag GetRegionSpaceFlag() const
{
return regionSpaceFlag_;
}
std::string Str() const
{
return GetEcmaOpcodeStr(opcode_);
@ -166,6 +176,7 @@ private:
std::vector<ElementsKind> elementsKinds_ {};
std::vector<ElementsKind> transitionElementsKinds_ {};
OnHeapMode onHeapMode_ {OnHeapMode::NONE};
RegionSpaceFlag regionSpaceFlag_ {RegionSpaceFlag::IN_YOUNG_SPACE};
};

View File

@ -203,7 +203,8 @@ void NTypeBytecodeLowering::LowerNTypedCreateEmptyArray(GateRef gate)
AddProfiling(gate);
ElementsKind kind = acc_.TryGetElementsKind(gate);
uint32_t length = acc_.TryGetArrayElementsLength(gate);
GateRef array = builder_.CreateArray(kind, 0, builder_.Int64(length));
RegionSpaceFlag flag = acc_.TryGetRegionSpaceFlag(gate);
GateRef array = builder_.CreateArray(kind, 0, builder_.Int64(length), flag);
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), array);
}
@ -223,9 +224,11 @@ void NTypeBytecodeLowering::LowerNTypedCreateArrayWithBuffer(GateRef gate)
}
AddProfiling(gate);
ElementsKind kind = acc_.TryGetElementsKind(gate);
RegionSpaceFlag flag = acc_.TryGetRegionSpaceFlag(gate);
GateRef cpIdGr = builder_.Int32(cpId);
GateRef array =
builder_.CreateArrayWithBuffer(kind, ArrayMetaDataAccessor::Mode::CREATE, cpIdGr, index);
builder_.CreateArrayWithBuffer(kind, ArrayMetaDataAccessor::Mode::CREATE,
cpIdGr, index, flag);
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), array);
}

View File

@ -204,6 +204,10 @@ GateRef NTypeHCRLowering::NewJSArrayLiteral(GateRef glue, GateRef gate, GateRef
uint32_t hintLength)
{
ElementsKind kind = acc_.GetArrayMetaDataAccessor(gate).GetElementsKind();
RegionSpaceFlag flag = RegionSpaceFlag::IN_YOUNG_SPACE;
if (enablePgoSpace_) {
flag = acc_.GetArrayMetaDataAccessor(gate).GetRegionSpaceFlag();
}
GateRef hclass = Circuit::NullGate();
if (!Elements::IsGeneric(kind)) {
// At define point, we use initial array class without IsPrototype set.
@ -225,7 +229,7 @@ GateRef NTypeHCRLowering::NewJSArrayLiteral(GateRef glue, GateRef gate, GateRef
GateRef size = builder_.IntPtr(arrayHC->GetObjectSize());
builder_.StartAllocate();
GateRef array = builder_.HeapAlloc(glue, size, GateType::TaggedValue(), RegionSpaceFlag::IN_YOUNG_SPACE);
GateRef array = builder_.HeapAlloc(glue, size, GateType::TaggedValue(), flag);
// initialization
for (size_t offset = JSArray::SIZE; offset < arraySize; offset += JSTaggedValue::TaggedTypeSize()) {
builder_.StoreConstOffset(VariableType::INT64(), array, offset, builder_.Undefined());

View File

@ -24,7 +24,7 @@ namespace panda::ecmascript::kungfu {
class NTypeHCRLowering : public PassVisitor {
public:
NTypeHCRLowering(Circuit *circuit, RPOVisitor *visitor, PassContext *ctx, const CString &recordName,
const MethodLiteral *methodLiteral, Chunk* chunk)
const MethodLiteral *methodLiteral, bool enablePgoSpace, Chunk* chunk)
: PassVisitor(circuit, chunk, visitor),
circuit_(circuit),
acc_(circuit),
@ -35,6 +35,7 @@ public:
recordName_(recordName),
methodLiteral_(methodLiteral),
profiling_(ctx->GetCompilerConfig()->IsProfiling()),
enablePgoSpace_(enablePgoSpace),
traceBc_(ctx->GetCompilerConfig()->IsTraceBC()),
glue_(acc_.GetGlueFromArgList()) {}
@ -87,6 +88,7 @@ private:
const MethodLiteral *methodLiteral_ {nullptr};
panda_file::File::EntityId methodId_ {0};
bool profiling_ {false};
bool enablePgoSpace_ {false};
bool traceBc_ {false};
GateRef glue_ {Circuit::NullGate()};
};

View File

@ -450,8 +450,9 @@ public:
bool enableLog = data->GetLog()->EnableMethodCIRLog();
Chunk chunk(data->GetNativeAreaAllocator());
CombinedPassVisitor visitor(data->GetCircuit(), enableLog, data->GetMethodName(), &chunk);
JSRuntimeOptions runtimeOption = data->GetPassContext()->GetCompilationEnv()->GetJSOptions();
NTypeHCRLowering lowering(data->GetCircuit(), &visitor, data->GetPassContext(),
data->GetRecordName(), data->GetMethodLiteral(), &chunk);
data->GetRecordName(), data->GetMethodLiteral(), runtimeOption.IsCompilerEnablePgoSpace(), &chunk);
visitor.AddPass(&lowering);
visitor.VisitGraph();
visitor.PrintLog("NTypeHCRLowering");

View File

@ -111,6 +111,15 @@ uint32_t PGOTypeRecorder::GetElementsLength(int32_t offset) const
return 0;
}
RegionSpaceFlag PGOTypeRecorder::GetRegionSpaceFlag(int32_t offset) const
{
if (bcOffsetPGODefOpTypeMap_.find(offset) != bcOffsetPGODefOpTypeMap_.end()) {
const auto iter = bcOffsetPGODefOpTypeMap_.at(offset);
return iter->GetSpaceFlag();
}
return RegionSpaceFlag::IN_YOUNG_SPACE;
}
PGOTypeRef PGOTypeRecorder::GetPGOType(int32_t offset) const
{
if (bcOffsetPGOOpTypeMap_.find(offset) != bcOffsetPGOOpTypeMap_.end()) {

View File

@ -39,6 +39,7 @@ public:
std::vector<ElementsKind> PUBLIC_API GetTransitionElementsKindsForUser(int32_t offset) const;
ElementsKind PUBLIC_API GetElementsKindForCreater(int32_t offset) const;
uint32_t PUBLIC_API GetElementsLength(int32_t offset) const;
RegionSpaceFlag PUBLIC_API GetRegionSpaceFlag(int32_t offset) const;
PGOTypeRef PUBLIC_API GetPGOType(int32_t offset) const;

View File

@ -78,12 +78,19 @@ bool PostSchedule::VisitHeapAlloc(GateRef gate, ControlFlowGraph &cfg, size_t bb
int64_t flag = static_cast<int64_t>(acc_.TryGetValue(gate));
ASSERT(flag == RegionSpaceFlag::IN_YOUNG_SPACE ||
flag == RegionSpaceFlag::IN_SHARED_OLD_SPACE ||
flag == RegionSpaceFlag::IN_SHARED_NON_MOVABLE);
flag == RegionSpaceFlag::IN_SHARED_NON_MOVABLE ||
flag == RegionSpaceFlag::IN_OLD_SPACE);
std::vector<GateRef> currentBBGates;
std::vector<GateRef> successBBGates;
std::vector<GateRef> failBBGates;
std::vector<GateRef> endBBGates;
LoweringHeapAllocAndPrepareScheduleGate(gate, currentBBGates, successBBGates, failBBGates, endBBGates, flag);
if (flag == RegionSpaceFlag::IN_OLD_SPACE) {
LoweringHeapAllocate(gate, currentBBGates, successBBGates, failBBGates, endBBGates, flag);
ReplaceGateDirectly(currentBBGates, cfg, bbIdx, instIdx);
return false;
} else {
LoweringHeapAllocAndPrepareScheduleGate(gate, currentBBGates, successBBGates, failBBGates, endBBGates, flag);
}
#ifdef ARK_ASAN_ON
ReplaceGateDirectly(currentBBGates, cfg, bbIdx, instIdx);
return false;
@ -335,6 +342,8 @@ void PostSchedule::LoweringHeapAllocate(GateRef gate,
id = RTSTUB_ID(AllocateInSOld);
} else if (flag == RegionSpaceFlag::IN_SHARED_NON_MOVABLE) {
id = RTSTUB_ID(AllocateInSNonMovable);
} else if (flag == RegionSpaceFlag::IN_OLD_SPACE) {
id = RTSTUB_ID(AllocateInOld);
} else {
ASSERT(flag == RegionSpaceFlag::IN_YOUNG_SPACE);
}

View File

@ -25,6 +25,7 @@
#include "ecmascript/js_thread_hclass_entries.h"
#include "ecmascript/mem/chunk.h"
#include "ecmascript/mem/chunk_containers.h"
#include "ecmascript/mem/region.h"
#include "ecmascript/pgo_profiler/types/pgo_profiler_type.h"
#include "libpandabase/macros.h"
@ -501,9 +502,16 @@ public:
static constexpr int BITS_SIZE = 8;
static constexpr int ARRAY_LENGTH_BITS_SIZE = 32;
explicit ArrayMetaDataAccessor(uint64_t value) : bitField_(value) {}
explicit ArrayMetaDataAccessor(ElementsKind kind, Mode mode, uint32_t length = 0)
explicit ArrayMetaDataAccessor(ElementsKind kind, Mode mode,
uint32_t length = 0, RegionSpaceFlag flag = RegionSpaceFlag::IN_YOUNG_SPACE)
{
bitField_ = ElementsKindBits::Encode(kind) | ModeBits::Encode(mode) | ArrayLengthBits::Encode(length);
bitField_ = ElementsKindBits::Encode(kind) | ModeBits::Encode(mode) |
ArrayLengthBits::Encode(length) | RegionSpaceFlagBits::Encode(flag);
}
RegionSpaceFlag GetRegionSpaceFlag() const
{
return RegionSpaceFlagBits::Get(bitField_);
}
ElementsKind GetElementsKind() const
@ -526,6 +534,11 @@ public:
bitField_ = ArrayLengthBits::Update(bitField_, length);
}
void SetRegionSpaceFlag(RegionSpaceFlag flag)
{
bitField_ = RegionSpaceFlagBits::Update(bitField_, flag);
}
uint32_t GetArrayLength() const
{
return ArrayLengthBits::Get(bitField_);
@ -550,6 +563,7 @@ private:
using ElementsKindBits = panda::BitField<ElementsKind, 0, BITS_SIZE>;
using ModeBits = ElementsKindBits::NextField<Mode, BITS_SIZE>;
using ArrayLengthBits = ModeBits::NextField<uint32_t, ARRAY_LENGTH_BITS_SIZE>;
using RegionSpaceFlagBits = ArrayLengthBits::NextField<RegionSpaceFlag, BITS_SIZE>;
uint64_t bitField_;
};

View File

@ -91,6 +91,8 @@ void PGOTypeInfer::InferCreateArray(GateRef gate)
}
auto length = builder_->GetArrayElementsLength(gate);
acc_.TrySetArrayElementsLength(gate, length);
auto regionSpaceFlag = builder_->GetRegionSpaceFlag(gate);
acc_.TrySetRegionSpaceFlag(gate, regionSpaceFlag);
ElementsKind kind = builder_->GetElementsKindForCreater(gate);
if (Elements::IsGeneric(kind)) {
return;

View File

@ -171,6 +171,7 @@ const std::string PUBLIC_API HELP_OPTION_MSG =
"--compiler-enable-jit: Enable jit: Default: 'false'\n"
"--compiler-enable-osr: Enable osr: Default: 'false'\n"
"--compiler-enable-framework-aot: Enable frame aot: Default: 'true'\n"
"--compiler-enable-pgo-space: Enable pgo space used for compiler. Default: 'true'\n"
"--compiler-jit-hotness-threshold: Set hotness threshold for jit. Default: '2'\n"
"--compiler-jit-call-threshold: Set call threshold for jit. Default: '0'\n"
"--compiler-osr-hotness-threshold: Set hotness threshold for osr. Default: '2'\n"
@ -333,6 +334,7 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
{"compiler-codesign-disable", required_argument, nullptr, OPTION_CODESIGN_DISABLE},
{"compiler-enable-async-copytofort", required_argument, nullptr, OPTION_ENABLE_ASYNC_COPYTOFORT},
{"compiler-pgo-force-dump", required_argument, nullptr, OPTION_COMPILER_PGO_FORCE_DUMP},
{"compiler-enable-pgo-space", required_argument, nullptr, OPTION_COMPILER_ENABLE_PGO_SPACE},
{"async-load-abc", required_argument, nullptr, OPTION_ASYNC_LOAD_ABC},
{"async-load-abc-test", required_argument, nullptr, OPTION_ASYNC_LOAD_ABC_TEST},
{"compiler-enable-concurrent", required_argument, nullptr, OPTION_COMPILER_ENABLE_CONCURRENT},
@ -1318,6 +1320,14 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
return false;
}
break;
case OPTION_COMPILER_ENABLE_PGO_SPACE:
ret = ParseBoolParam(&argBool);
if (ret) {
SetCompilerEnablePgoSpace(argBool);
} else {
return false;
}
break;
default:
LOG_ECMA(ERROR) << "Invalid option\n";
return false;

View File

@ -216,6 +216,7 @@ enum CommandValues {
OPTION_COMPILER_OPT_FRAME_STATE_ELIMINATION,
OPTION_COMPILER_EMPTY_CATCH_FUNCTION,
OPTION_ENABLE_FORCE_IC,
OPTION_COMPILER_ENABLE_PGO_SPACE,
};
static_assert(OPTION_SPLIT_ONE == 64); // add new option at the bottom, DO NOT modify this value
static_assert(OPTION_SPLIT_TWO == 128); // add new option at the bottom, DO NOT modify this value
@ -1964,6 +1965,17 @@ public:
{
return aotHasException_;
}
void SetCompilerEnablePgoSpace(bool value)
{
enablePgoSpace_ = value;
}
bool IsCompilerEnablePgoSpace() const
{
return enablePgoSpace_;
}
public:
static constexpr int32_t MAX_APP_COMPILE_METHOD_SIZE = 4_KB;
@ -2126,6 +2138,7 @@ private:
bool enableLiteCG_ {false};
bool enableTypedOpProfiler_ {false};
bool enableBranchProfiling_ {true};
bool enablePgoSpace_ {false};
bool testAssert_ {false};
std::pair<uint32_t, uint32_t> compileMethodsRange_ {0, UINT32_MAX};
arg_list_t compileCodegenOption_ {{""}};

View File

@ -302,27 +302,26 @@ TaggedObject *Heap::TryAllocateYoungGeneration(JSHClass *hclass, size_t size)
TaggedObject *Heap::AllocateOldOrHugeObject(JSHClass *hclass)
{
size_t size = hclass->GetObjectSize();
TaggedObject *object = AllocateOldOrHugeObject(hclass, size);
if (object == nullptr) {
LOG_ECMA(FATAL) << "Heap::AllocateOldOrHugeObject:object is nullptr";
return AllocateOldOrHugeObject(hclass, size);
}
TaggedObject *Heap::AllocateOldOrHugeObject(size_t size)
{
size = AlignUp(size, static_cast<size_t>(MemAlignment::MEM_ALIGN_OBJECT));
TaggedObject *object = nullptr;
if (size > MAX_REGULAR_HEAP_OBJECT_SIZE) {
object = AllocateHugeObject(size);
} else {
object = reinterpret_cast<TaggedObject *>(oldSpace_->Allocate(size));
CHECK_OBJ_AND_THROW_OOM_ERROR(object, size, oldSpace_, "Heap::AllocateOldOrHugeObject");
}
#if defined(ECMASCRIPT_SUPPORT_HEAPPROFILER)
OnAllocateEvent(GetEcmaVM(), object, size);
#endif
return object;
}
TaggedObject *Heap::AllocateOldOrHugeObject(JSHClass *hclass, size_t size)
{
size = AlignUp(size, static_cast<size_t>(MemAlignment::MEM_ALIGN_OBJECT));
TaggedObject *object = nullptr;
if (size > MAX_REGULAR_HEAP_OBJECT_SIZE) {
object = AllocateHugeObject(hclass, size);
} else {
object = reinterpret_cast<TaggedObject *>(oldSpace_->Allocate(size));
CHECK_OBJ_AND_THROW_OOM_ERROR(object, size, oldSpace_, "Heap::AllocateOldOrHugeObject");
object->SetClass(thread_, hclass);
}
auto object = AllocateOldOrHugeObject(size);
object->SetClass(thread_, hclass);
#if defined(ECMASCRIPT_SUPPORT_HEAPPROFILER)
OnAllocateEvent(GetEcmaVM(), reinterpret_cast<TaggedObject*>(object), size);
#endif

View File

@ -1077,11 +1077,13 @@ public:
// Old
inline TaggedObject *AllocateOldOrHugeObject(JSHClass *hclass);
inline TaggedObject *AllocateOldOrHugeObject(JSHClass *hclass, size_t size);
inline TaggedObject *AllocateOldOrHugeObject(size_t size);
// Non-movable
inline TaggedObject *AllocateNonMovableOrHugeObject(JSHClass *hclass);
inline TaggedObject *AllocateNonMovableOrHugeObject(JSHClass *hclass, size_t size);
inline TaggedObject *AllocateClassClass(JSHClass *hclass, size_t size);
// Huge
inline TaggedObject *AllocateHugeObject(size_t size);
inline TaggedObject *AllocateHugeObject(JSHClass *hclass, size_t size);
// Machine code
inline TaggedObject *AllocateMachineCodeObject(JSHClass *hclass, size_t size, MachineCodeDesc *desc = nullptr);
@ -1478,7 +1480,6 @@ public:
PUBLIC_API void RemoveGCListener(GCListenerId listenerId);
void ProcessGCListeners();
private:
inline TaggedObject *AllocateHugeObject(size_t size);
static constexpr int MIN_JSDUMP_THRESHOLDS = 85;
static constexpr int MAX_JSDUMP_THRESHOLDS = 95;

View File

@ -78,6 +78,8 @@ public:
if (type.GetProfileType().IsArrayLiteralType()) {
const_cast<PGODefineOpTemplate<ProfileType> *>(&((*result).GetTypeRef()))
->SetElementsKind(type.GetElementsKind());
const_cast<PGODefineOpTemplate<ProfileType> *>(&((*result).GetTypeRef()))
->SetSpaceFlag(type.GetSpaceFlag());
}
return;
}

View File

@ -288,6 +288,7 @@ void PGOProfiler::UpdateTrackSpaceFlag(TaggedObject *object, RegionSpaceFlag spa
RegionSpaceFlag oldFlag = trackInfo->GetSpaceFlag();
if (oldFlag == RegionSpaceFlag::IN_YOUNG_SPACE) {
trackInfo->SetSpaceFlag(spaceFlag);
UpdateTrackInfo(JSTaggedValue(trackInfo));
}
}
@ -296,6 +297,7 @@ void PGOProfiler::UpdateTrackInfo(JSTaggedValue trackInfoVal)
if (trackInfoVal.IsHeapObject()) {
auto trackInfo = TrackInfo::Cast(trackInfoVal.GetTaggedObject());
auto func = trackInfo->GetCachedFunc();
auto thread = vm_->GetJSThread();
if (!func.IsWeak()) {
return;
}
@ -303,8 +305,12 @@ void PGOProfiler::UpdateTrackInfo(JSTaggedValue trackInfoVal)
if (!object->GetClass()->IsJSFunction()) {
return;
}
auto profileTypeInfoVal = JSFunction::Cast(object)->GetProfileTypeInfo();
if (profileTypeInfoVal.IsUndefined()) {
JSFunction* function = JSFunction::Cast(object);
if (!function->HasProfileTypeInfo(thread)) {
return;
}
auto profileTypeInfoVal = function->GetProfileTypeInfo();
if (profileTypeInfoVal.IsUndefined() || !profileTypeInfoVal.IsTaggedArray()) {
return;
}
auto profileTypeInfo = ProfileTypeInfo::Cast(profileTypeInfoVal.GetTaggedObject());

View File

@ -195,6 +195,7 @@ namespace panda::ecmascript {
V(AddElementInternal) \
V(HeapAlloc) \
V(AllocateInYoung) \
V(AllocateInOld) \
V(AllocateInSOld) \
V(AllocateInSNonMovable) \
V(TypedArraySpeciesCreate) \

View File

@ -166,6 +166,22 @@ DEF_RUNTIME_STUBS(AllocateInYoung)
return JSTaggedValue(result).GetRawData();
}
DEF_RUNTIME_STUBS(AllocateInOld)
{
RUNTIME_STUBS_HEADER(AllocateInOld);
JSTaggedValue allocateSize = GetArg(argv, argc, 0); // 0: means the zeroth parameter
auto size = static_cast<size_t>(allocateSize.GetLargeUInt());
auto heap = const_cast<Heap*>(thread->GetEcmaVM()->GetHeap());
auto result = heap->AllocateOldOrHugeObject(size);
ASSERT(result != nullptr);
if (argc > 1) { // 1: means the first parameter
JSHandle<JSHClass> hclassHandle = GetHArg<JSHClass>(argv, argc, 1); // 1: means the first parameter
auto hclass = JSHClass::Cast(hclassHandle.GetTaggedValue().GetTaggedObject());
heap->SetHClassAndDoAllocateEvent(thread, result, hclass, size);
}
return JSTaggedValue(result).GetRawData();
}
#define ALLOCATE_IN_SHARED_HEAP(SPACE) \
DEF_RUNTIME_STUBS(AllocateInS##SPACE) \
{ \

View File

@ -344,6 +344,7 @@
panda::ecmascript::kungfu::PGOTypeRecorder::GetElementsKindsForUser*;
panda::ecmascript::kungfu::PGOTypeRecorder::GetElementsLength*;
panda::ecmascript::kungfu::PGOTypeRecorder::GetPGOType*;
panda::ecmascript::kungfu::PGOTypeRecorder::GetRegionSpaceFlag*;
panda::ecmascript::kungfu::PGOTypeRecorder::GetTransitionElementsKindForUser*;
panda::ecmascript::kungfu::PGOTypeRecorder::GetTransitionElementsKindsForUser*;
panda::ecmascript::kungfu::PGOTypeRecorder::PGOTypeRecorder*;

View File

@ -255,6 +255,7 @@ group("ark_aot_ts_test") {
#"pgo_call_with_repetitive_method_id",
"pgo_char_to_string_deopt",
"pgo_on_heap",
"pgo_space_flag",
"pgo_store_deopt",
"pgo_track_type",
"poplexenv",

View File

@ -0,0 +1,25 @@
# 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.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("pgo_space_flag") {
deps = []
is_only_typed_path = true
is_enable_inline_trace = true
is_enable_opt_inlining = true
is_enable_pgo = true
is_enable_pgo_space = true
is_enable_trace_deopt = true
is_enable_enableArkTools = true
}

View File

@ -0,0 +1,17 @@
# 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.
false
true
false
true

View File

@ -0,0 +1,17 @@
# 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.
true
false
false
true

View File

@ -0,0 +1,24 @@
/*
* 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.
*/
let a = [];
print(ArkTools.inYoungSpace(a));
print(ArkTools.inOldSpace(a));
for (let t = 0; t < 100000; t++) {
a[t] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
a[t][0];
}
print(ArkTools.inYoungSpace(a));
print(ArkTools.inOldSpace(a));

View File

@ -1279,6 +1279,10 @@ template("host_aot_js_test_action") {
_aot_compile_options_ += " --compiler-opt-loop-peeling=false"
}
if (defined(invoker.is_enable_pgo_space) && invoker.is_enable_pgo_space) {
_aot_compile_options_ += " --compiler-enable-pgo-space=true"
}
args = [
"--script-file",
rebase_path(_root_out_dir_) + "/arkcompiler/ets_runtime/ark_aot_compiler",
@ -1558,6 +1562,10 @@ template("host_aot_js_test_action") {
_aot_compile_options_ += " --compiler-opt-loop-peeling=false"
}
if (defined(invoker.is_enable_pgo_space) && invoker.is_enable_pgo_space) {
_aot_compile_options_ += " --compiler-enable-pgo-space=true"
}
_aot_compile_options_ += common_options
args = [
"--script-file",
@ -1821,6 +1829,10 @@ template("host_aot_js_test_action") {
_aot_compile_options_ += " --compiler-opt-loop-peeling=false"
}
if (defined(invoker.is_enable_pgo_space) && invoker.is_enable_pgo_space) {
_aot_compile_options_ += " --compiler-enable-pgo-space=true"
}
_aot_compile_options_ += common_options
args = [
"--script-file",
@ -2161,6 +2173,10 @@ template("host_aot_js_assert_test_action") {
_aot_compile_options_ += " --compiler-opt-loop-peeling=true"
}
if (defined(invoker.is_enable_pgo_space) && invoker.is_enable_pgo_space) {
_aot_compile_options_ += " --compiler-enable-pgo-space=true"
}
if (defined(invoker.is_enable_opt_array_bounds_check_elimination) &&
invoker.is_enable_opt_array_bounds_check_elimination) {
_aot_compile_options_ +=
@ -2616,6 +2632,10 @@ template("host_aot_test_action") {
_aot_compile_options_ += " --compiler-opt-loop-peeling=false"
}
if (defined(invoker.is_enable_pgo_space) && invoker.is_enable_pgo_space) {
_aot_compile_options_ += " --compiler-enable-pgo-space=true"
}
_aot_compile_options_ += common_options
args = [
"--script-file",
@ -2707,6 +2727,10 @@ template("host_aot_test_action") {
_aot_compile_options_ += " --compiler-opt-loop-peeling=false"
}
if (defined(invoker.is_enable_pgo_space) && invoker.is_enable_pgo_space) {
_aot_compile_options_ += " --compiler-enable-pgo-space=true"
}
_aot_compile_options_ += common_options
args = [
"--script-file",
@ -2796,6 +2820,7 @@ template("host_aot_test_action") {
invoker.is_enable_trace_deopt) {
_aot_run_options_ += " --compiler-trace-deopt=true"
}
args = [
"--script-file",
rebase_path(_root_out_dir_) + "/arkcompiler/ets_runtime/ark_js_vm",
@ -3047,6 +3072,10 @@ template("host_aot_test_action") {
_aot_compile_options_ += " --compiler-opt-loop-peeling=false"
}
if (defined(invoker.is_enable_pgo_space) && invoker.is_enable_pgo_space) {
_aot_compile_options_ += " --compiler-enable-pgo-space=true"
}
_aot_compile_options_ += common_options
args = [
"--script-file",
@ -3141,6 +3170,10 @@ template("host_aot_test_action") {
_aot_compile_options_ += " --compiler-opt-loop-peeling=false"
}
if (defined(invoker.is_enable_pgo_space) && invoker.is_enable_pgo_space) {
_aot_compile_options_ += " --compiler-enable-pgo-space=true"
}
_aot_compile_options_ += common_options
args = [
"--script-file",
@ -3471,6 +3504,10 @@ template("host_aot_test_action") {
_aot_compile_options_ += " --compiler-opt-loop-peeling=false"
}
if (defined(invoker.is_enable_pgo_space) && invoker.is_enable_pgo_space) {
_aot_compile_options_ += " --compiler-enable-pgo-space=true"
}
_aot_compile_options_ += common_options
args = [
"--script-file",
@ -3566,6 +3603,10 @@ template("host_aot_test_action") {
_aot_compile_options_ += " --compiler-opt-loop-peeling=false"
}
if (defined(invoker.is_enable_pgo_space) && invoker.is_enable_pgo_space) {
_aot_compile_options_ += " --compiler-enable-pgo-space=true"
}
_aot_compile_options_ += common_options
args = [
"--script-file",
@ -3980,6 +4021,10 @@ template("host_aot_assert_test_action") {
_aot_compile_options_ += " --compiler-opt-loop-peeling=true"
}
if (defined(invoker.is_enable_pgo_space) && invoker.is_enable_pgo_space) {
_aot_compile_options_ += " --compiler-enable-pgo-space=true"
}
if (defined(invoker.is_enable_opt_array_bounds_check_elimination) &&
invoker.is_enable_opt_array_bounds_check_elimination) {
_aot_compile_options_ +=
@ -4071,6 +4116,10 @@ template("host_aot_assert_test_action") {
_aot_compile_options_ += " --compiler-opt-loop-peeling=true"
}
if (defined(invoker.is_enable_pgo_space) && invoker.is_enable_pgo_space) {
_aot_compile_options_ += " --compiler-enable-pgo-space=true"
}
if (defined(invoker.is_enable_opt_array_bounds_check_elimination) &&
invoker.is_enable_opt_array_bounds_check_elimination) {
_aot_compile_options_ +=