!1341 support inline new for asm interpreter

Merge pull request !1341 from 孙哲/master
This commit is contained in:
openharmony_ci 2022-05-19 09:49:11 +00:00 committed by Gitee
commit 7ad9f41154
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
14 changed files with 241 additions and 30 deletions

View File

@ -333,7 +333,9 @@ DECLARE_ASM_HANDLER(HandleNewLexEnvDynPrefImm16)
DEFVARIABLE(varAcc, VariableType::JS_ANY(), acc);
auto env = GetEnvironment();
GateRef numVars = ReadInst16_1(pc);
GateRef res = CallRuntime(glue, RTSTUB_ID(NewLexicalEnvDyn), { Int16BuildTaggedTypeWithNoGC(numVars) });
GateRef state = GetFrame(sp);
auto parent = GetEnvFromFrame(state);
GateRef res = NewLexicalEnv(glue, ZExtInt16ToInt32(numVars), parent);
Label isException(env);
Label notException(env);
Branch(TaggedIsException(res), &isException, &notException);
@ -1960,7 +1962,7 @@ DECLARE_ASM_HANDLER(HandleIncDynPrefV8)
}
}
Bind(&valueNotInt);
if (!env->IsAmd64()) {
{
Label valueIsDouble(env);
Label valueNotDouble(env);
Branch(TaggedIsDouble(value), &valueIsDouble, &valueNotDouble);
@ -1972,8 +1974,6 @@ DECLARE_ASM_HANDLER(HandleIncDynPrefV8)
}
Bind(&valueNotDouble);
Jump(&slowPath);
} else {
Jump(&slowPath);
}
Bind(&slowPath);
{
@ -2018,7 +2018,7 @@ DECLARE_ASM_HANDLER(HandleDecDynPrefV8)
}
}
Bind(&valueNotInt);
if (!env->IsAmd64()) {
{
Label valueIsDouble(env);
Label valueNotDouble(env);
Branch(TaggedIsDouble(value), &valueIsDouble, &valueNotDouble);
@ -2030,8 +2030,6 @@ DECLARE_ASM_HANDLER(HandleDecDynPrefV8)
}
Bind(&valueNotDouble);
Jump(&slowPath);
} else {
Jump(&slowPath);
}
Bind(&slowPath);
{
@ -5630,7 +5628,7 @@ void InterpreterStub::JSCallDispatch(GateRef glue, GateRef func, GateRef actualN
GateRef acc = TaggedArgument(static_cast<size_t>(InterpreterHandlerInputs::ACC));
GateRef hotnessCounter = Int32Argument(
static_cast<size_t>(InterpreterHandlerInputs::HOTNESS_COUNTER));
// 1. call initialize
Label funcIsHeapObject(env);
Label funcIsCallable(env);

View File

@ -82,7 +82,7 @@ struct CodeInfo {
machineCode_ = nullptr;
}
uint8_t *AllocaCodeSection(uintptr_t size, const char *sectionName)
uint8_t *Alloca(uintptr_t size, const char *sectionName)
{
uint8_t *addr = nullptr;
if (codeBufferPos_ + size > MAX_MACHINE_CODE_SIZE) {
@ -92,13 +92,22 @@ struct CodeInfo {
}
codeSectionNames_.push_back(sectionName);
addr = machineCode_ + codeBufferPos_;
codeInfo_.push_back({addr, size});
codeBufferPos_ += size;
return addr;
}
uint8_t *AllocaCodeSection(uintptr_t size, const char *sectionName)
{
uint8_t *addr = Alloca(size, sectionName);
codeInfo_.push_back({addr, size});
return addr;
}
uint8_t *AllocaDataSection(uintptr_t size, const char *sectionName)
{
if (strncmp(sectionName, ".rodata", strlen(".rodata")) == 0) {
return Alloca(size, sectionName);
}
uint8_t *addr = nullptr;
dataSectionList_.push_back(std::vector<uint8_t>());
dataSectionList_.back().resize(size);

View File

@ -877,6 +877,11 @@ inline GateRef Stub::Int64UnsignedLessThanOrEqual(GateRef x, GateRef y)
return env_.GetBulder()->BinaryLogic(OpCode(OpCode::ULE), x, y);
}
inline GateRef Stub::IntPtrGreaterThan(GateRef x, GateRef y)
{
return env_.Is32Bit() ? Int32GreaterThan(x, y) : Int64GreaterThan(x, y);
}
// cast operation
inline GateRef Stub::ChangeInt64ToInt32(GateRef val)
{
@ -1793,7 +1798,7 @@ inline void Stub::SetHasConstructorToHClass(GateRef glue, GateRef hClass, GateRe
Store(VariableType::INT32(), glue, hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET), newVal);
}
inline GateRef Stub::IntptrEuqal(GateRef x, GateRef y)
inline GateRef Stub::IntPtrEuqal(GateRef x, GateRef y)
{
return env_.Is32Bit() ? Int32Equal(x, y) : Int64Equal(x, y);
}
@ -1992,5 +1997,18 @@ inline GateRef Stub::GetTargetFromJSProxy(GateRef proxy)
GateRef offset = IntPtr(JSProxy::TARGET_OFFSET);
return Load(VariableType::JS_ANY(), proxy, offset);
}
inline GateRef Stub::ComputeTaggedArraySize(GateRef length)
{
return PtrAdd(IntPtr(TaggedArray::DATA_OFFSET),
PtrMul(IntPtr(JSTaggedValue::TaggedTypeSize()), length));
}
inline GateRef Stub::GetGlobalConstantValue(VariableType type, GateRef glue, ConstantIndex index)
{
GateRef gConstAddr = PtrAdd(glue,
IntPtr(JSThread::GlueData::GetGlobalConstOffset(env_.Is32Bit())));
auto constantIndex = IntPtr(JSTaggedValue::TaggedTypeSize() * static_cast<size_t>(index));
return Load(type, gConstAddr, constantIndex);
}
} // namespace panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_STUB_INL_H

View File

@ -873,7 +873,7 @@ void Stub::SetValueWithBarrier(GateRef glue, GateRef obj, GateRef offset, GateRe
auto oldToNewSet = Load(VariableType::NATIVE_POINTER(), objectRegion, loadOffset);
Label isNullPtr(env);
Label notNullPtr(env);
Branch(IntptrEuqal(oldToNewSet, IntPtr(0)), &isNullPtr, &notNullPtr);
Branch(IntPtrEuqal(oldToNewSet, IntPtr(0)), &isNullPtr, &notNullPtr);
Bind(&notNullPtr);
{
// (slotAddr - this) >> TAGGED_TYPE_SIZE_LOG
@ -3575,4 +3575,109 @@ GateRef Stub::GetHashcodeFromString(GateRef glue, GateRef value)
env->SubCfgExit();
return ret;
}
GateRef Stub::AllocateInYoung(GateRef glue, GateRef size)
{
auto env = GetEnvironment();
Label entry(env);
env->SubCfgEntry(&entry);
Label exit(env);
Label success(env);
Label callRuntime(env);
auto topOffset = JSThread::GlueData::GetNewSpaceAllocationTopAddressOffset(env->Is32Bit());
auto endOffset = JSThread::GlueData::GetNewSpaceAllocationEndAddressOffset(env->Is32Bit());
auto topAddress = Load(VariableType::NATIVE_POINTER(), glue, IntPtr(topOffset));
auto endAddress = Load(VariableType::NATIVE_POINTER(), glue, IntPtr(endOffset));
auto top = Load(VariableType::NATIVE_POINTER(), topAddress, IntPtr(0));
auto end = Load(VariableType::NATIVE_POINTER(), endAddress, IntPtr(0));
DEFVARIABLE(result, VariableType::INT64(), Undefined());
auto newTop = PtrAdd(top, size);
Branch(IntPtrGreaterThan(newTop, end), &callRuntime, &success);
Bind(&success);
{
Store(VariableType::NATIVE_POINTER(), glue, topAddress, IntPtr(0), newTop);
if (env->Is32Bit()) {
top = ZExtInt32ToInt64(top);
}
result = top;
Jump(&exit);
}
Bind(&callRuntime);
{
result = TaggedCastToInt64(CallRuntime(glue, RTSTUB_ID(AllocateInYoung), {
IntBuildTaggedTypeWithNoGC(size) }));
Jump(&exit);
}
Bind(&exit);
auto ret = *result;
env->SubCfgExit();
return ret;
}
void Stub::InitializeTaggedArrayWithSpeicalValue(
GateRef glue, GateRef array, GateRef value, GateRef start, GateRef length)
{
auto env = GetEnvironment();
Label entry(env);
env->SubCfgEntry(&entry);
Label exit(env);
Label begin(env);
Label storeValue(env);
Label end(env);
Store(VariableType::INT32(), glue, array, IntPtr(TaggedArray::LENGTH_OFFSET), length);
DEFVARIABLE(i, VariableType::INT32(), start);
Jump(&begin);
LoopBegin(&begin);
{
Branch(Int32UnsignedLessThan(*i, length), &storeValue, &exit);
Bind(&storeValue);
{
SetValueToTaggedArray(VariableType::INT64(), glue, array, *i, value);
i = Int32Add(*i, Int32(1));
Jump(&end);
}
Bind(&end);
LoopEnd(&begin);
}
Bind(&exit);
env->SubCfgExit();
}
GateRef Stub::NewLexicalEnv(GateRef glue, GateRef numSlots, GateRef parent)
{
auto env = GetEnvironment();
Label entry(env);
env->SubCfgEntry(&entry);
Label exit(env);
auto length = Int32Add(numSlots, Int32(LexicalEnv::RESERVED_ENV_LENGTH));
auto size = ComputeTaggedArraySize(ChangeInt32ToIntPtr(length));
// Be careful. NO GC is allowed when initization is not complete.
auto object = AllocateInYoung(glue, size);
Label hasPendingException(env);
Label noException(env);
Branch(TaggedIsException(object), &hasPendingException, &noException);
Bind(&noException);
{
auto hclass = GetGlobalConstantValue(
VariableType::JS_POINTER(), glue, ConstantIndex::ENV_CLASS_INDEX);
StoreHClass(glue, object, hclass);
InitializeTaggedArrayWithSpeicalValue(glue,
object, Hole(), Int32(LexicalEnv::RESERVED_ENV_LENGTH), length);
SetValueToTaggedArray(VariableType::INT64(),
glue, object, Int32(LexicalEnv::SCOPE_INFO_INDEX), Hole());
SetValueToTaggedArray(VariableType::JS_POINTER(),
glue, object, Int32(LexicalEnv::PARENT_ENV_INDEX), parent);
Jump(&exit);
}
Bind(&hasPendingException);
{
Jump(&exit);
}
Bind(&exit);
env->SubCfgExit();
return ChangeInt64ToTagged(object);
}
} // namespace panda::ecmascript::kungfu

View File

@ -216,6 +216,7 @@ public:
GateRef Int64LessThanOrEqual(GateRef x, GateRef y);
GateRef Int64GreaterThanOrEqual(GateRef x, GateRef y);
GateRef Int64UnsignedLessThanOrEqual(GateRef x, GateRef y);
GateRef IntPtrGreaterThan(GateRef x, GateRef y);
// cast operation
GateRef ChangeInt64ToInt32(GateRef val);
GateRef ChangeInt64ToIntPtr(GateRef val);
@ -394,7 +395,7 @@ public:
void SetHasConstructorToHClass(GateRef glue, GateRef hClass, GateRef value);
void UpdateValueInDict(GateRef glue, GateRef elements, GateRef index, GateRef value);
GateRef GetBitMask(GateRef bitoffset);
GateRef IntptrEuqal(GateRef x, GateRef y);
GateRef IntPtrEuqal(GateRef x, GateRef y);
void SetValueWithBarrier(GateRef glue, GateRef obj, GateRef offset, GateRef value);
GateRef GetPropertyByIndex(GateRef glue, GateRef receiver, GateRef index);
GateRef GetPropertyByName(GateRef glue, GateRef receiver, GateRef key);
@ -447,6 +448,13 @@ public:
GateRef GetHandlerFromJSProxy(GateRef proxy);
GateRef GetTargetFromJSProxy(GateRef proxy);
inline void SavePcIfNeeded(GateRef glue);
inline GateRef ComputeTaggedArraySize(GateRef length);
inline GateRef GetGlobalConstantValue(
VariableType type, GateRef glue, ConstantIndex index);
void InitializeTaggedArrayWithSpeicalValue(
GateRef glue, GateRef array, GateRef value, GateRef start, GateRef length);
GateRef AllocateInYoung(GateRef glue, GateRef size);
GateRef NewLexicalEnv(GateRef glue, GateRef numSlots, GateRef parent);
private:
using BinaryOperation = std::function<GateRef(Environment*, GateRef, GateRef)>;
template<OpCode::Op Op>

View File

@ -166,6 +166,11 @@ public:
nestedLevel_ = level;
}
void SetLastFp(JSTaggedType *fp)
{
glueData_.lastFp_ = fp;
}
const JSTaggedType *GetCurrentSPFrame() const
{
return glueData_.currentFrame_;
@ -186,16 +191,6 @@ public:
glueData_.leaveFrame_ = sp;
}
const JSTaggedType *GetLastFp() const
{
return glueData_.lastFp_;
}
void SetLastFp(JSTaggedType *fp)
{
glueData_.lastFp_ = fp;
}
const JSTaggedType *GetCurrentFrame() const;
void SetCurrentFrame(JSTaggedType *sp);
@ -214,6 +209,12 @@ public:
return heapRegionAllocator_;
}
void ReSetNewSpaceAllocationAddress(const uintptr_t *top, const uintptr_t* end)
{
glueData_.newSpaceAllocationTopAddress_ = top;
glueData_.newSpaceAllocationEndAddress_ = end;
}
void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1);
uintptr_t* PUBLIC_API ExpandHandleStorage();
@ -425,6 +426,8 @@ public:
base::AlignedPointer,
base::AlignedPointer,
base::AlignedPointer,
base::AlignedPointer,
base::AlignedPointer,
BCStubEntries,
RTStubEntries,
COStubEntries,
@ -438,6 +441,8 @@ public:
CurrentFrameIndex,
LeaveFrameIndex,
LastFpIndex,
NewSpaceAllocationTopAddressIndex,
NewSpaceAllocationEndAddressIndex,
BCStubEntriesIndex,
RTStubEntriesIndex,
COStubEntriesIndex,
@ -484,6 +489,16 @@ public:
return GetOffset<static_cast<size_t>(Index::LastFpIndex)>(isArch32);
}
static size_t GetNewSpaceAllocationTopAddressOffset(bool isArch32)
{
return GetOffset<static_cast<size_t>(Index::NewSpaceAllocationTopAddressIndex)>(isArch32);
}
static size_t GetNewSpaceAllocationEndAddressOffset(bool isArch32)
{
return GetOffset<static_cast<size_t>(Index::NewSpaceAllocationEndAddressIndex)>(isArch32);
}
static size_t GetBCStubEntriesOffset(bool isArch32)
{
return GetOffset<static_cast<size_t>(Index::BCStubEntriesIndex)>(isArch32);
@ -514,6 +529,8 @@ public:
alignas(EAS) JSTaggedType *currentFrame_ {nullptr};
alignas(EAS) JSTaggedType *leaveFrame_ {nullptr};
alignas(EAS) JSTaggedType *lastFp_ {nullptr};
alignas(EAS) const uintptr_t *newSpaceAllocationTopAddress_ {nullptr};
alignas(EAS) const uintptr_t *newSpaceAllocationEndAddress_ {nullptr};
alignas(EAS) BCStubEntries bcStubEntries_;
alignas(EAS) RTStubEntries rtStubEntries_;
alignas(EAS) COStubEntries coStubEntries_;

View File

@ -57,6 +57,16 @@ public:
return end_;
}
const uintptr_t *GetTopAddress()
{
return &top_;
}
const uintptr_t *GetEndAddress()
{
return &end_;
}
size_t Available() const
{
return (end_ - top_);

View File

@ -108,11 +108,11 @@ TaggedObject *Heap::AllocateYoungOrHugeObject(JSHClass *hclass)
return AllocateYoungOrHugeObject(hclass, size);
}
TaggedObject *Heap::AllocateYoungOrHugeObject(JSHClass *hclass, size_t size)
TaggedObject *Heap::AllocateYoungOrHugeObject(size_t size)
{
size = AlignUp(size, static_cast<size_t>(MemAlignment::MEM_ALIGN_OBJECT));
if (size > MAX_REGULAR_HEAP_OBJECT_SIZE) {
return AllocateHugeObject(hclass, size);
return AllocateHugeObject(size);
}
auto object = reinterpret_cast<TaggedObject *>(activeSpace_->Allocate(size));
@ -128,7 +128,12 @@ TaggedObject *Heap::AllocateYoungOrHugeObject(JSHClass *hclass, size_t size)
}
}
}
return object;
}
TaggedObject *Heap::AllocateYoungOrHugeObject(JSHClass *hclass, size_t size)
{
auto object = AllocateYoungOrHugeObject(size);
object->SetClass(hclass);
OnAllocateEvent(reinterpret_cast<uintptr_t>(object));
return object;
@ -218,7 +223,7 @@ TaggedObject *Heap::AllocateDynClassClass(JSHClass *hclass, size_t size)
return object;
}
TaggedObject *Heap::AllocateHugeObject(JSHClass *hclass, size_t size)
TaggedObject *Heap::AllocateHugeObject(size_t size)
{
// Check whether it is necessary to trigger Old GC before expanding to avoid OOM risk.
CheckAndTriggerOldGC();
@ -231,6 +236,14 @@ TaggedObject *Heap::AllocateHugeObject(JSHClass *hclass, size_t size)
ThrowOutOfMemoryError(size, "Heap::AllocateHugeObject");
}
}
return object;
}
TaggedObject *Heap::AllocateHugeObject(JSHClass *hclass, size_t size)
{
// Check whether it is necessary to trigger Old GC before expanding to avoid OOM risk.
CheckAndTriggerOldGC();
auto object = AllocateHugeObject(size);
object->SetClass(hclass);
OnAllocateEvent(reinterpret_cast<uintptr_t>(object));
return object;
@ -286,6 +299,9 @@ void Heap::SwapNewSpace()
SemiSpace *newSpace = inactiveSpace_;
inactiveSpace_ = activeSpace_;
activeSpace_ = newSpace;
auto topAddress = activeSpace_->GetAllocationTopAddress();
auto endAddress = activeSpace_->GetAllocationEndAddress();
thread_->ReSetNewSpaceAllocationAddress(topAddress, endAddress);
}
void Heap::ReclaimRegions(TriggerGCType gcType)

View File

@ -54,6 +54,9 @@ void Heap::Initialize()
activeSpace_ = new SemiSpace(this, defaultSemiSpaceCapacity, defaultSemiSpaceCapacity);
activeSpace_->Restart();
activeSpace_->SetWaterLine();
auto topAddress = activeSpace_->GetAllocationTopAddress();
auto endAddress = activeSpace_->GetAllocationEndAddress();
thread_->ReSetNewSpaceAllocationAddress(topAddress, endAddress);
inactiveSpace_ = new SemiSpace(this, defaultSemiSpaceCapacity, defaultSemiSpaceCapacity);
// not set up from space

View File

@ -190,6 +190,7 @@ public:
// Young
inline TaggedObject *AllocateYoungOrHugeObject(JSHClass *hclass);
inline TaggedObject *AllocateYoungOrHugeObject(JSHClass *hclass, size_t size);
inline TaggedObject *AllocateYoungOrHugeObject(size_t size);
inline uintptr_t AllocateYoungSync(size_t size);
inline TaggedObject *TryAllocateYoungGeneration(JSHClass *hclass, size_t size);
// Old
@ -201,6 +202,7 @@ public:
inline TaggedObject *AllocateDynClassClass(JSHClass *hclass, size_t size);
// Huge
inline TaggedObject *AllocateHugeObject(JSHClass *hclass, size_t size);
inline TaggedObject *AllocateHugeObject(size_t size);
// Machine code
inline TaggedObject *AllocateMachineCodeObject(JSHClass *hclass, size_t size);
// Snapshot

View File

@ -31,6 +31,14 @@ public:
{
survivalObjectSize_ -= objSize;
}
const uintptr_t *GetAllocationTopAddress()
{
return allocator_->GetTopAddress();
}
const uintptr_t *GetAllocationEndAddress()
{
return allocator_->GetEndAddress();
}
protected:
Heap *heap_ {nullptr};

View File

@ -74,6 +74,22 @@ DEF_RUNTIME_STUBS(AddElementInternal)
return JSTaggedValue(result).GetRawData();
}
DEF_RUNTIME_STUBS(AllocateInYoung)
{
RUNTIME_STUBS_HEADER(AllocateInYoung);
JSTaggedValue allocateSize = GetArg(argv, argc, 0);
auto size = static_cast<size_t>(allocateSize.GetInt());
auto heap = const_cast<Heap*>(thread->GetEcmaVM()->GetHeap());
auto space = heap->GetNewSpace();
ASSERT(size <= MAX_REGULAR_HEAP_OBJECT_SIZE);
auto result = reinterpret_cast<TaggedObject *>(space->Allocate(size));
if (result == nullptr) {
result = heap->AllocateYoungOrHugeObject(size);
ASSERT(result != nullptr);
}
return JSTaggedValue(result).GetRawData();
}
DEF_RUNTIME_STUBS(CallSetter)
{
RUNTIME_STUBS_HEADER(CallSetter);

View File

@ -130,6 +130,7 @@ extern "C" void ResumeCaughtFrameAndDispatch(uintptr_t glue, uintptr_t pc, uintp
#define RUNTIME_STUB_WITH_GC_LIST(V) \
V(AddElementInternal) \
V(AllocateInYoung) \
V(CallSetter) \
V(CallSetter2) \
V(CallGetter) \

View File

@ -19,8 +19,8 @@
#ifdef PANDA_TARGET_64
#define ASM_GLUE_CURRENT_FRAME_OFFSET (16)
#define ASM_GLUE_LEAVE_FRAME_OFFSET (24)
#define ASM_GLUE_BC_HANDLERS_OFFSET (40)
#define ASM_GLUE_RUNTIME_FUNCTIONS_OFFSET (2088)
#define ASM_GLUE_BC_HANDLERS_OFFSET (56)
#define ASM_GLUE_RUNTIME_FUNCTIONS_OFFSET (2104)
#define ASM_BASE_FUNCTION_METHOD_OFFSET (32)
#define ASM_JS_METHOD_CALLFIELD_OFFSET (0)
#define ASM_JS_METHOD_BYTECODEARRAY_OFFSET (8)
@ -61,8 +61,8 @@
#ifdef PANDA_TARGET_32
#define ASM_GLUE_CURRENT_FRAME_OFFSET (16)
#define ASM_GLUE_LEAVE_FRAME_OFFSET (24)
#define ASM_GLUE_BC_HANDLERS_OFFSET (40)
#define ASM_GLUE_RUNTIME_FUNCTIONS_OFFSET (1064)
#define ASM_GLUE_BC_HANDLERS_OFFSET (56)
#define ASM_GLUE_RUNTIME_FUNCTIONS_OFFSET (1080)
#define ASM_BASE_FUNCTION_METHOD_OFFSET (32)
#define ASM_JS_METHOD_CALLFIELD_OFFSET (0)
#define ASM_JS_METHOD_BYTECODEARRAY_OFFSET (8)