!2276 Class 、 Layout And JSFunction Filed optimization.

Merge pull request !2276 from yingguofeng/master
This commit is contained in:
openharmony_ci 2022-09-06 04:24:14 +00:00 committed by Gitee
commit cbbb74b5a5
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
20 changed files with 187 additions and 129 deletions

View File

@ -1427,8 +1427,8 @@ inline GateRef StubBuilder::IsAccessorInternal(GateRef value)
inline GateRef StubBuilder::GetPropAttrFromLayoutInfo(GateRef layout, GateRef entry)
{
GateRef index = Int32Add(Int32Add(Int32(LayoutInfo::ELEMENTS_START_INDEX),
Int32LSL(entry, Int32(1))), Int32(1));
GateRef index = Int32Add(Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2)),
Int32(LayoutInfo::ATTR_INDEX_OFFSET));
return GetValueFromTaggedArray(VariableType::INT64(), layout, index);
}
@ -1440,17 +1440,13 @@ inline GateRef StubBuilder::GetPropertyMetaDataFromAttr(GateRef attr)
inline GateRef StubBuilder::GetKeyFromLayoutInfo(GateRef layout, GateRef entry)
{
GateRef index = Int32Add(
Int32(LayoutInfo::ELEMENTS_START_INDEX),
Int32LSL(entry, Int32(1)));
GateRef index = Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2));
return GetValueFromTaggedArray(VariableType::JS_ANY(), layout, index);
}
inline GateRef StubBuilder::GetPropertiesAddrFromLayoutInfo(GateRef layout)
{
GateRef eleStartIdx = PtrMul(IntPtr(LayoutInfo::ELEMENTS_START_INDEX),
IntPtr(JSTaggedValue::TaggedTypeSize()));
return PtrAdd(layout, PtrAdd(IntPtr(TaggedArray::DATA_OFFSET), eleStartIdx));
return PtrAdd(layout, IntPtr(TaggedArray::DATA_OFFSET));
}
inline GateRef StubBuilder::TaggedCastToInt64(GateRef x)

View File

@ -42,6 +42,14 @@ CString *HeapSnapshot::GetString(const CString &as)
return stringTable_.GetString(as);
}
CString *HeapSnapshot::GetArrayString(TaggedArray *array, const CString &as)
{
CString arrayName = as;
arrayName.append(ToCString(array->GetLength()));
arrayName.append("]");
return GetString(arrayName); // String type was handled singly, see#GenerateStringNode
}
Node *Node::NewNode(const EcmaVM *vm, size_t id, size_t index, CString *name, NodeType type, size_t size,
TaggedObject *entry, bool isLive)
{
@ -197,40 +205,16 @@ CString *HeapSnapshot::GenerateNodeName(TaggedObject *entry)
auto *hCls = entry->GetClass();
JSType type = hCls->GetObjectType();
switch (type) {
case JSType::TAGGED_ARRAY: {
CString arrayName;
TaggedArray *array = TaggedArray::Cast(entry);
arrayName = "TaggedArray[";
arrayName.append(ToCString(array->GetLength()));
arrayName.append("]");
return GetString(arrayName); // String type was handled singly, see#GenerateStringNode
}
case JSType::LEXICAL_ENV: {
CString arrayName;
TaggedArray *array = TaggedArray::Cast(entry);
arrayName = "LexicalEnv[";
arrayName.append(ToCString(array->GetLength()));
arrayName.append("]");
return GetString(arrayName); // String type was handled singly, see#GenerateStringNode
}
case JSType::CONSTANT_POOL: {
CString arrayName;
ConstantPool *constantPool = ConstantPool::Cast(entry);
arrayName = "ConstantPool[";
arrayName.append(ToCString(constantPool->GetCacheLength()));
arrayName.append("]");
return GetString(arrayName); // String type was handled singly, see#GenerateStringNode
}
case JSType::TAGGED_ARRAY:
return GetArrayString(TaggedArray::Cast(entry), "TaggedArray[");
case JSType::LEXICAL_ENV:
return GetArrayString(TaggedArray::Cast(entry), "LexicalEnv[");
case JSType::CONSTANT_POOL:
return GetArrayString(TaggedArray::Cast(entry), "ConstantPool[");
case JSType::TAGGED_DICTIONARY:
return GetArrayString(TaggedArray::Cast(entry), "TaggedDict[");
case JSType::HCLASS:
return GetString("HiddenClass");
case JSType::TAGGED_DICTIONARY: {
CString dictName;
TaggedArray *dict = TaggedArray::Cast(entry);
dictName = "TaggedDict[";
dictName.append(ToCString(dict->GetLength()));
dictName.append("]");
return GetString(dictName);
}
case JSType::STRING:
return GetString("BaseString");
case JSType::JS_OBJECT: {
@ -240,9 +224,9 @@ CString *HeapSnapshot::GenerateNodeName(TaggedObject *entry)
case JSType::FREE_OBJECT_WITH_ONE_FIELD:
case JSType::FREE_OBJECT_WITH_NONE_FIELD:
case JSType::FREE_OBJECT_WITH_TWO_FIELD:
case JSType::JS_NATIVE_POINTER: {
break;
}
return GetString("FreeObject");
case JSType::JS_NATIVE_POINTER:
return GetString("JSNativePointer");
case JSType::JS_FUNCTION_BASE:
return GetString("JSFunctionBase");
case JSType::JS_FUNCTION:
@ -545,7 +529,7 @@ CString *HeapSnapshot::GenerateNodeName(TaggedObject *entry)
} else {
return GetString("Hidden Object");
}
return GetString("UnKnownType");
return GetString(CString("UnKnownType").append(std::to_string(static_cast<int>(type))));
}
NodeType HeapSnapshot::GenerateNodeType(TaggedObject *entry)

View File

@ -409,6 +409,7 @@ public:
}
CString *GetString(const CString &as);
CString *GetArrayString(TaggedArray *array, const CString &as);
bool IsInVmMode() const
{

View File

@ -4071,7 +4071,6 @@ void JSFunction::DumpForSnapshot(std::vector<std::pair<CString, JSTaggedValue>>
vec.push_back(std::make_pair(CString("Strict"), JSTaggedValue(GetStrict())));
vec.push_back(std::make_pair(CString("Resolved"), JSTaggedValue(GetResolved())));
vec.push_back(std::make_pair(CString("ThisMode"), JSTaggedValue(static_cast<int>(GetThisMode()))));
vec.push_back(std::make_pair(CString("FunctionExtraInfo"), GetFunctionExtraInfo()));
vec.push_back(std::make_pair(CString("ProfileTypeInfo"), GetProfileTypeInfo()));
JSObject::DumpForSnapshot(vec);
}

View File

@ -631,29 +631,37 @@ void JSFunction::SetFunctionExtraInfo(JSThread *thread, void *nativeFunc, const
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(hashField));
JSHandle<ECMAObject> obj(thread, this);
JSHandle<JSNativePointer> pointer = vm->GetFactory()->NewJSNativePointer(nativeFunc, deleter, data);
if (value->IsTaggedArray()) {
if (!HasHash()) {
Barriers::SetDynObject<true>(thread, *obj, HASH_OFFSET, pointer.GetTaggedValue().GetRawData());
return;
}
if (value->IsHeapObject()) {
if (value->IsJSNativePointer()) {
Barriers::SetDynObject<true>(thread, *obj, HASH_OFFSET, pointer.GetTaggedValue().GetRawData());
return;
}
JSHandle<TaggedArray> array(value);
uint32_t nativeFieldCount = array->GetExtractLength();
uint32_t nativeFieldCount = array->GetExtraLength();
if (array->GetLength() >= nativeFieldCount + RESOLVED_MAX_SIZE) {
array->Set(thread, nativeFieldCount + FUNCTION_EXTRAL_INDEX, pointer);
array->Set(thread, nativeFieldCount + FUNCTION_EXTRA_INDEX, pointer);
} else {
JSHandle<TaggedArray> newArray =
thread->GetEcmaVM()->GetFactory()->NewTaggedArray(nativeFieldCount + RESOLVED_MAX_SIZE);
newArray->SetExtractLength(nativeFieldCount);
newArray->SetExtraLength(nativeFieldCount);
for (uint32_t i = 0; i < nativeFieldCount; i++) {
newArray->Set(thread, i, array->Get(i));
}
newArray->Set(thread, nativeFieldCount + HASH_INDEX, array->Get(nativeFieldCount + HASH_INDEX));
newArray->Set(thread, nativeFieldCount + FUNCTION_EXTRAL_INDEX, pointer);
newArray->Set(thread, nativeFieldCount + FUNCTION_EXTRA_INDEX, pointer);
Barriers::SetDynObject<true>(thread, *obj, HASH_OFFSET, newArray.GetTaggedValue().GetRawData());
}
} else {
JSHandle<TaggedArray> newArray =
thread->GetEcmaVM()->GetFactory()->NewTaggedArray(RESOLVED_MAX_SIZE);
newArray->SetExtractLength(0);
newArray->SetExtraLength(0);
newArray->Set(thread, HASH_INDEX, value);
newArray->Set(thread, FUNCTION_EXTRAL_INDEX, pointer);
newArray->Set(thread, FUNCTION_EXTRA_INDEX, pointer);
Barriers::SetDynObject<true>(thread, *obj, HASH_OFFSET, newArray.GetTaggedValue().GetRawData());
}
}
@ -662,11 +670,17 @@ JSTaggedValue JSFunction::GetFunctionExtraInfo() const
{
JSTaggedType hashField = Barriers::GetDynValue<JSTaggedType>(this, HASH_OFFSET);
JSTaggedValue value(hashField);
if (value.IsTaggedArray()) {
TaggedArray *array = TaggedArray::Cast(value.GetTaggedObject());
uint32_t nativeFieldCount = array->GetExtractLength();
if (array->GetLength() >= nativeFieldCount + RESOLVED_MAX_SIZE) {
return array->Get(nativeFieldCount + FUNCTION_EXTRAL_INDEX);
if (value.IsHeapObject()) {
if (value.IsTaggedArray()) {
TaggedArray *array = TaggedArray::Cast(value.GetTaggedObject());
uint32_t nativeFieldCount = array->GetExtraLength();
if (array->GetLength() >= nativeFieldCount + RESOLVED_MAX_SIZE) {
return array->Get(nativeFieldCount + FUNCTION_EXTRA_INDEX);
}
} else if (value.IsJSNativePointer()) {
return value;
} else {
UNREACHABLE();
}
}
return JSTaggedValue::Undefined();

View File

@ -197,7 +197,7 @@ JSHandle<JSHClass> JSHClass::SetPropertyOfObjHClass(const JSThread *thread, JSHa
layoutInfoHandle.Update(factory->CopyAndReSort(layoutInfoHandle, offset, offset + 1));
} else if (layoutInfoHandle->GetPropertiesCapacity() <= static_cast<int>(offset)) { // need to Grow
layoutInfoHandle.Update(
factory->ExtendLayoutInfo(layoutInfoHandle, LayoutInfo::ComputeGrowCapacity(offset)));
factory->ExtendLayoutInfo(layoutInfoHandle, offset));
}
newJshclass->SetLayout(thread, layoutInfoHandle);
layoutInfoHandle->AddKey(thread, offset, key.GetTaggedValue(), attr);
@ -235,7 +235,7 @@ void JSHClass::AddProperty(const JSThread *thread, const JSHandle<JSObject> &obj
layoutInfoHandle.Update(factory->CopyAndReSort(layoutInfoHandle, offset, offset + 1));
} else if (layoutInfoHandle->GetPropertiesCapacity() <= static_cast<int>(offset)) { // need to Grow
layoutInfoHandle.Update(
factory->ExtendLayoutInfo(layoutInfoHandle, LayoutInfo::ComputeGrowCapacity(offset)));
factory->ExtendLayoutInfo(layoutInfoHandle, offset));
}
newJshclass->SetLayout(thread, layoutInfoHandle);
layoutInfoHandle->AddKey(thread, offset, key.GetTaggedValue(), attr);

View File

@ -1952,15 +1952,27 @@ bool JSObject::UpdatePropertyInDictionary(const JSThread *thread, JSTaggedValue
return true;
}
// The hash field may be a hash value, FunctionExtraInfo(JSNativePointer) or TaggedArray
void ECMAObject::SetHash(int32_t hash)
{
JSTaggedType hashField = Barriers::GetDynValue<JSTaggedType>(this, HASH_OFFSET);
JSTaggedValue value(hashField);
if (value.IsHeapObject()) {
JSThread *thread = this->GetJSThread();
ASSERT(value.IsTaggedArray());
TaggedArray *array = TaggedArray::Cast(value.GetTaggedObject());
array->Set(thread, array->GetExtractLength() + HASH_INDEX, JSTaggedValue(hash));
// Hash position reserve in advance.
if (value.IsTaggedArray()) {
TaggedArray *array = TaggedArray::Cast(value.GetTaggedObject());
array->Set(thread, array->GetExtraLength() + HASH_INDEX, JSTaggedValue(hash));
} else if (value.IsNativePointer()) { // FunctionExtraInfo
JSHandle<TaggedArray> newArray =
thread->GetEcmaVM()->GetFactory()->NewTaggedArray(RESOLVED_MAX_SIZE);
newArray->SetExtraLength(0);
newArray->Set(thread, HASH_INDEX, JSTaggedValue(hash));
newArray->Set(thread, FUNCTION_EXTRA_INDEX, value);
Barriers::SetDynObject<true>(thread, this, HASH_OFFSET, newArray.GetTaggedValue().GetRawData());
} else {
UNREACHABLE();
}
} else {
Barriers::SetDynPrimitive<JSTaggedType>(this, HASH_OFFSET, JSTaggedValue(hash).GetRawData());
}
@ -1971,22 +1983,37 @@ int32_t ECMAObject::GetHash() const
JSTaggedType hashField = Barriers::GetDynValue<JSTaggedType>(this, HASH_OFFSET);
JSTaggedValue value(hashField);
if (value.IsHeapObject()) {
TaggedArray *array = TaggedArray::Cast(value.GetTaggedObject());
return array->Get(array->GetExtractLength() + HASH_INDEX).GetInt();
if (value.IsTaggedArray()) {
TaggedArray *array = TaggedArray::Cast(value.GetTaggedObject());
return array->Get(array->GetExtraLength() + HASH_INDEX).GetInt();
} else {
// Default is 0
return 0;
}
}
JSThread *thread = this->GetJSThread();
JSHandle<JSTaggedValue> valueHandle(thread, value);
return JSTaggedValue::ToInt32(thread, valueHandle);
}
bool ECMAObject::HasHash() const
{
JSTaggedType hashField = Barriers::GetDynValue<JSTaggedType>(this, HASH_OFFSET);
JSTaggedValue value(hashField);
if (value.IsInt() && value.GetInt() == 0) {
return false;
}
return true;
}
void *ECMAObject::GetNativePointerField(int32_t index) const
{
JSTaggedType hashField = Barriers::GetDynValue<JSTaggedType>(this, HASH_OFFSET);
JSTaggedValue value(hashField);
if (value.IsHeapObject()) {
if (value.IsTaggedArray()) {
JSThread *thread = this->GetJSThread();
JSHandle<TaggedArray> array(thread, value);
if (static_cast<int32_t>(array->GetExtractLength()) > index) {
if (static_cast<int32_t>(array->GetExtraLength()) > index) {
JSHandle<JSNativePointer> pointer(thread, array->Get(index));
return pointer->GetExternalPointer();
}
@ -1999,10 +2026,10 @@ void ECMAObject::SetNativePointerField(int32_t index, void *nativePointer,
{
JSTaggedType hashField = Barriers::GetDynValue<JSTaggedType>(this, HASH_OFFSET);
JSTaggedValue value(hashField);
if (value.IsHeapObject()) {
if (value.IsTaggedArray()) {
JSThread *thread = this->GetJSThread();
JSHandle<TaggedArray> array(thread, value);
if (static_cast<int32_t>(array->GetExtractLength()) > index) {
if (static_cast<int32_t>(array->GetExtraLength()) > index) {
EcmaVM *vm = thread->GetEcmaVM();
JSHandle<JSTaggedValue> current = JSHandle<JSTaggedValue>(thread, array->Get(thread, index));
if (!current->IsHole() && nativePointer == nullptr) {
@ -2023,9 +2050,9 @@ int32_t ECMAObject::GetNativePointerFieldCount() const
int32_t len = 0;
JSTaggedType hashField = Barriers::GetDynValue<JSTaggedType>(this, HASH_OFFSET);
JSTaggedValue value(hashField);
if (value.IsHeapObject()) {
if (value.IsTaggedArray()) {
TaggedArray *array = TaggedArray::Cast(value.GetTaggedObject());
len = static_cast<int32_t>(array->GetExtractLength());
len = static_cast<int32_t>(array->GetExtraLength());
}
return len;
}
@ -2039,23 +2066,33 @@ void ECMAObject::SetNativePointerFieldCount(int32_t count)
JSThread *thread = this->GetJSThread();
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(hashField));
JSHandle<ECMAObject> obj(thread, this);
if (!value->IsHeapObject()) {
JSHandle<TaggedArray> newArray = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(count + 1);
newArray->SetExtractLength(count);
newArray->Set(thread, count + HASH_INDEX, value);
Barriers::SetDynObject<true>(thread, *obj, HASH_OFFSET, newArray.GetTaggedValue().GetRawData());
} else {
ASSERT(value->IsTaggedArray());
JSHandle<TaggedArray> array(value);
// Native Pointer field count is fixed.
if (array->GetExtractLength() == 0) {
if (value->IsHeapObject()) {
if (value->IsTaggedArray()) {
JSHandle<TaggedArray> array(value);
// Native Pointer field count is fixed.
if (array->GetExtraLength() == 0) {
JSHandle<TaggedArray> newArray =
thread->GetEcmaVM()->GetFactory()->NewTaggedArray(count + RESOLVED_MAX_SIZE);
newArray->SetExtraLength(count);
newArray->Set(thread, count + HASH_INDEX, array->Get(HASH_INDEX));
newArray->Set(thread, count + FUNCTION_EXTRA_INDEX, array->Get(FUNCTION_EXTRA_INDEX));
Barriers::SetDynObject<true>(thread, *obj, HASH_OFFSET, newArray.GetTaggedValue().GetRawData());
}
} else if (value->IsJSNativePointer()) {
JSHandle<TaggedArray> newArray =
thread->GetEcmaVM()->GetFactory()->NewTaggedArray(count + RESOLVED_MAX_SIZE);
newArray->SetExtractLength(count);
newArray->Set(thread, count + HASH_INDEX, array->Get(HASH_INDEX));
newArray->Set(thread, count + FUNCTION_EXTRAL_INDEX, array->Get(FUNCTION_EXTRAL_INDEX));
newArray->SetExtraLength(count);
newArray->Set(thread, count + HASH_INDEX, JSTaggedValue(0));
newArray->Set(thread, count + FUNCTION_EXTRA_INDEX, value);
Barriers::SetDynObject<true>(thread, *obj, HASH_OFFSET, newArray.GetTaggedValue().GetRawData());
} else {
UNREACHABLE();
}
} else {
JSHandle<TaggedArray> newArray = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(count + 1);
newArray->SetExtraLength(count);
newArray->Set(thread, count + HASH_INDEX, value);
Barriers::SetDynObject<true>(thread, *obj, HASH_OFFSET, newArray.GetTaggedValue().GetRawData());
}
}
} // namespace panda::ecmascript

View File

@ -325,7 +325,7 @@ private:
class ECMAObject : public TaggedObject {
public:
static constexpr int HASH_INDEX = 0;
static constexpr int FUNCTION_EXTRAL_INDEX = 1;
static constexpr int FUNCTION_EXTRA_INDEX = 1;
static constexpr int RESOLVED_MAX_SIZE = 2;
CAST_CHECK(ECMAObject, IsECMAObject);
@ -339,6 +339,8 @@ public:
void SetHash(int32_t hash);
int32_t GetHash() const;
bool HasHash() const;
void InitializeHash()
{
Barriers::SetDynPrimitive<JSTaggedType>(this, ECMAObject::HASH_OFFSET, JSTaggedValue(0).GetRawData());

View File

@ -30,7 +30,10 @@ void ClassInfoExtractor::BuildClassInfoExtractorFromLiteral(JSThread *thread, JS
uint32_t literalBufferLength = literal->GetLength();
// non static properties number is hidden in the last index of Literal buffer
uint32_t nonStaticNum = static_cast<uint32_t>(literal->Get(thread, literalBufferLength - 1).GetInt());
uint32_t nonStaticNum = 0;
if (literalBufferLength != 0) {
nonStaticNum = static_cast<uint32_t>(literal->Get(thread, literalBufferLength - 1).GetInt());
}
// Reserve sufficient length to prevent frequent creation.
JSHandle<TaggedArray> nonStaticKeys = factory->NewOldSpaceTaggedArray(nonStaticNum + NON_STATIC_RESERVED_LENGTH);
@ -39,11 +42,10 @@ void ClassInfoExtractor::BuildClassInfoExtractorFromLiteral(JSThread *thread, JS
nonStaticKeys->Set(thread, CONSTRUCTOR_INDEX, globalConst->GetConstructorString());
JSHandle<TaggedArray> nonStaticElements = factory->EmptyArray();
if (nonStaticNum) {
ExtractContentsDetail nonStaticDetail {0, nonStaticNum * 2, NON_STATIC_RESERVED_LENGTH, nullptr};
JSHandle<TaggedArray> nonStaticElements = factory->EmptyArray();
if (UNLIKELY(ExtractAndReturnWhetherWithElements(thread, literal, nonStaticDetail, nonStaticKeys,
nonStaticProperties, nonStaticElements))) {
extractor->SetNonStaticWithElements(true);
@ -54,7 +56,7 @@ void ClassInfoExtractor::BuildClassInfoExtractorFromLiteral(JSThread *thread, JS
extractor->SetNonStaticKeys(thread, nonStaticKeys);
extractor->SetNonStaticProperties(thread, nonStaticProperties);
uint32_t staticNum = (literalBufferLength - 1) / 2 - nonStaticNum;
uint32_t staticNum = literalBufferLength == 0 ? 0 : (literalBufferLength - 1) / 2 - nonStaticNum;
// Reserve sufficient length to prevent frequent creation.
JSHandle<TaggedArray> staticKeys = factory->NewOldSpaceTaggedArray(staticNum + STATIC_RESERVED_LENGTH);
@ -176,7 +178,7 @@ JSHandle<JSHClass> ClassInfoExtractor::CreatePrototypeHClass(JSThread *thread, J
JSHandle<JSHClass> hclass;
if (LIKELY(length <= PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES)) {
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(length, MemSpaceType::OLD_SPACE);
JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(length, MemSpaceType::OLD_SPACE, GrowMode::KEEP);
for (uint32_t index = 0; index < length; ++index) {
key.Update(keys->Get(index));
ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");
@ -217,7 +219,7 @@ JSHandle<JSHClass> ClassInfoExtractor::CreateConstructorHClass(JSThread *thread,
JSHandle<JSHClass> hclass;
if (LIKELY(length <= PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES)) {
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(length, MemSpaceType::OLD_SPACE);
JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(length, MemSpaceType::OLD_SPACE, GrowMode::KEEP);
for (uint32_t index = 0; index < length; ++index) {
key.Update(keys->Get(index));
ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");

View File

@ -23,8 +23,6 @@
#include "ecmascript/module/js_module_manager.h"
#include "ecmascript/tagged_array-inl.h"
#include "libpandafile/literal_data_accessor-inl.h"
namespace panda::ecmascript {
using LiteralTag = panda_file::LiteralTag;
using StringData = panda_file::StringData;
@ -123,17 +121,36 @@ void LiteralDataExtractor::ExtractObjectDatas(JSThread *thread, const JSPandaFil
});
}
JSHandle<TaggedArray> LiteralDataExtractor::GetDatasIgnoreTypeForClass(JSThread *thread,
const JSPandaFile *jsPandaFile, size_t index, JSHandle<JSTaggedValue> constpool, const CString &entryPoint)
{
const panda_file::File *pf = jsPandaFile->GetPandaFile();
panda_file::File::EntityId literalArraysId = pf->GetLiteralArraysId();
panda_file::LiteralDataAccessor lda(*pf, literalArraysId);
uint32_t num = lda.GetLiteralValsNum(index) / 2; // 2: half
// The num is 1, indicating that the current class has no member variable.
if (num == 1) {
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
return factory->EmptyArray();
}
return EnumerateLiteralVals(thread, lda, jsPandaFile, index, constpool, entryPoint);
}
JSHandle<TaggedArray> LiteralDataExtractor::GetDatasIgnoreType(JSThread *thread, const JSPandaFile *jsPandaFile,
size_t index, JSHandle<JSTaggedValue> constpool,
const CString &entryPoint)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
LOG_ECMA(VERBOSE) << "Panda File" << jsPandaFile->GetJSPandaFileDesc();
const panda_file::File *pf = jsPandaFile->GetPandaFile();
panda_file::File::EntityId literalArraysId = pf->GetLiteralArraysId();
panda_file::LiteralDataAccessor lda(*pf, literalArraysId);
return EnumerateLiteralVals(thread, lda, jsPandaFile, index, constpool, entryPoint);
}
JSHandle<TaggedArray> LiteralDataExtractor::EnumerateLiteralVals(JSThread *thread, panda_file::LiteralDataAccessor &lda,
const JSPandaFile *jsPandaFile, size_t index, JSHandle<JSTaggedValue> constpool, const CString &entryPoint)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
uint32_t num = lda.GetLiteralValsNum(index) / 2; // 2: half
JSHandle<TaggedArray> literals = factory->NewOldSpaceTaggedArray(num);
uint32_t pos = 0;

View File

@ -18,6 +18,7 @@
#include "ecmascript/jspandafile/panda_file_translator.h"
#include "ecmascript/js_tagged_value-inl.h"
#include "libpandafile/literal_data_accessor-inl.h"
namespace panda::ecmascript {
using EntityId = panda_file::File::EntityId;
@ -40,6 +41,12 @@ public:
static JSHandle<JSFunction> DefineMethodInLiteral(JSThread *thread, const JSPandaFile *jsPandaFile,
JSHandle<Method> method, FunctionKind kind, uint16_t length,
const CString &entryPoint = "");
static JSHandle<TaggedArray> GetDatasIgnoreTypeForClass(JSThread *thread, const JSPandaFile *jsPandaFile,
size_t index, JSHandle<JSTaggedValue> constpool, const CString &entryPoint = "");
private:
static JSHandle<TaggedArray> EnumerateLiteralVals(JSThread *thread, panda_file::LiteralDataAccessor &lda,
const JSPandaFile *jsPandaFile, size_t index, JSHandle<JSTaggedValue> constpool,
const CString &entryPoint = "");
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_JSPANDAFILE_LITERAL_DATA_EXTRACTOR_H

View File

@ -298,7 +298,7 @@ JSHandle<ConstantPool> PandaFileTranslator::ParseConstPool(EcmaVM *vm, const JSP
constpool->SetObjectToCache(thread, value.GetConstpoolIndex(), arr.GetTaggedValue());
} else if (value.GetConstpoolType() == ConstPoolType::CLASS_LITERAL) {
size_t index = it.first;
JSHandle<TaggedArray> literal = LiteralDataExtractor::GetDatasIgnoreType(
JSHandle<TaggedArray> literal = LiteralDataExtractor::GetDatasIgnoreTypeForClass(
thread, jsPandaFile, static_cast<size_t>(index), JSHandle<JSTaggedValue>(constpool), entryPoint);
if (isLoadedAOT) {
fileLoader->SetAOTFuncEntryForLiteral(jsPandaFile, literal);

View File

@ -63,11 +63,11 @@ public:
return TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), cacheSize + RESERVED_POOL_LENGTH);
}
inline void InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t capacity)
inline void InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t capacity, uint32_t extraLength = 0)
{
ASSERT(initValue.IsSpecial());
SetLength(capacity + RESERVED_POOL_LENGTH);
SetExtractLength(0);
SetExtraLength(extraLength);
for (uint32_t i = 0; i < capacity; i++) {
size_t offset = JSTaggedValue::TaggedTypeSize() * i;
Barriers::SetDynPrimitive<JSTaggedType>(GetData(), offset, initValue.GetRawData());

View File

@ -24,27 +24,27 @@
namespace panda::ecmascript {
inline int LayoutInfo::GetPropertiesCapacity() const
{
return static_cast<int>((GetLength() - ELEMENTS_START_INDEX) >> 1U);
return static_cast<int>((GetLength()) >> ELEMENTS_INDEX_LOG2);
}
inline int LayoutInfo::NumberOfElements() const
{
return TaggedArray::Get(NUMBER_OF_PROPERTIES_INDEX).GetInt();
return GetExtraLength();
}
inline void LayoutInfo::SetNumberOfElements(const JSThread *thread, int properties)
inline void LayoutInfo::SetNumberOfElements([[maybe_unused]] const JSThread *thread, int properties)
{
return TaggedArray::Set(thread, NUMBER_OF_PROPERTIES_INDEX, JSTaggedValue(properties));
SetExtraLength(properties);
}
inline uint32_t LayoutInfo::GetKeyIndex(int index) const
{
return ELEMENTS_START_INDEX + (static_cast<uint32_t>(index) << 1U);
return static_cast<uint32_t>(index) << ELEMENTS_INDEX_LOG2;
}
inline uint32_t LayoutInfo::GetAttrIndex(int index) const
{
return ELEMENTS_START_INDEX + (static_cast<uint32_t>(index) << 1U) + 1;
return (static_cast<uint32_t>(index) << ELEMENTS_INDEX_LOG2) + ATTR_INDEX_OFFSET;
}
inline void LayoutInfo::SetPropertyInit(const JSThread *thread, int index, const JSTaggedValue &key,
@ -52,7 +52,7 @@ inline void LayoutInfo::SetPropertyInit(const JSThread *thread, int index, const
{
uint32_t fixed_idx = GetKeyIndex(index);
TaggedArray::Set(thread, fixed_idx, key);
TaggedArray::Set(thread, fixed_idx + 1, attr.GetNormalTagged());
TaggedArray::Set(thread, fixed_idx + ATTR_INDEX_OFFSET, attr.GetNormalTagged());
}
inline void LayoutInfo::SetNormalAttr(const JSThread *thread, int index, const PropertyAttributes &attr)

View File

@ -30,8 +30,8 @@ class LayoutInfo : private TaggedArray {
public:
static constexpr int MIN_PROPERTIES_LENGTH = JSObject::MIN_PROPERTIES_LENGTH;
static constexpr int MAX_PROPERTIES_LENGTH = PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES;
static constexpr int NUMBER_OF_PROPERTIES_INDEX = 0;
static constexpr int ELEMENTS_START_INDEX = 1;
static constexpr uint32_t ELEMENTS_INDEX_LOG2 = 1;
static constexpr uint32_t ATTR_INDEX_OFFSET = 1;
inline static LayoutInfo *Cast(TaggedObject *obj)
{
@ -61,13 +61,12 @@ public:
inline Properties *GetProperties() const
{
return reinterpret_cast<Properties *>(reinterpret_cast<uintptr_t>(this) + TaggedArray::DATA_OFFSET +
ELEMENTS_START_INDEX * JSTaggedValue::TaggedTypeSize());
return reinterpret_cast<Properties *>(reinterpret_cast<uintptr_t>(this) + TaggedArray::DATA_OFFSET);
}
static inline uint32_t ComputeArrayLength(uint32_t properties_number)
{
return (properties_number << 1U) + ELEMENTS_START_INDEX;
return (properties_number << ELEMENTS_INDEX_LOG2);
}
static inline uint32_t ComputeGrowCapacity(uint32_t old_capacity)

View File

@ -393,8 +393,7 @@ JSHandle<TaggedArray> ObjectFactory::CloneProperties(const JSHandle<TaggedArray>
size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
auto header = heap_->AllocateYoungOrHugeObject(klass, size);
JSHandle<TaggedArray> newArray(thread_, header);
newArray->SetLength(newLength);
newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength);
newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
for (uint32_t i = 0; i < newLength; i++) {
JSTaggedValue value = old->Get(i);
newArray->Set(thread_, i, value);
@ -457,8 +456,7 @@ JSHandle<TaggedArray> ObjectFactory::CloneProperties(const JSHandle<TaggedArray>
size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
auto header = heap_->AllocateYoungOrHugeObject(klass, size);
JSHandle<TaggedArray> newArray(thread_, header);
newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength);
newArray->SetLength(newLength);
newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
for (uint32_t i = 0; i < newLength; i++) {
JSTaggedValue value = old->Get(i);
@ -1983,6 +1981,7 @@ JSHandle<TaggedArray> ObjectFactory::NewEmptyArray()
JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), TaggedArray::SIZE);
JSHandle<TaggedArray> array(thread_, header);
array->SetLength(0);
array->SetExtraLength(0);
return array;
}
@ -2102,6 +2101,7 @@ JSHandle<TaggedArray> ObjectFactory::ExtendArray(const JSHandle<TaggedArray> &ol
TaggedObject *header = AllocObjectWithSpaceType(size, arrayClass, type);
JSHandle<TaggedArray> newArray(thread_, header);
newArray->SetLength(length);
newArray->SetExtraLength(old->GetExtraLength());
uint32_t oldLength = old->GetLength();
for (uint32_t i = 0; i < oldLength; i++) {
@ -2132,8 +2132,7 @@ JSHandle<TaggedArray> ObjectFactory::CopyPartArray(const JSHandle<TaggedArray> &
auto header = heap_->AllocateYoungOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
JSHandle<TaggedArray> newArray(thread_, header);
newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength);
newArray->SetLength(newLength);
newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
for (uint32_t i = 0; i < newLength; i++) {
JSTaggedValue value = old->Get(i + start);
@ -2160,8 +2159,7 @@ JSHandle<TaggedArray> ObjectFactory::CopyArray(const JSHandle<TaggedArray> &old,
JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
TaggedObject *header = AllocObjectWithSpaceType(size, arrayClass, type);
JSHandle<TaggedArray> newArray(thread_, header);
newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength);
newArray->SetLength(newLength);
newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
for (uint32_t i = 0; i < newLength; i++) {
JSTaggedValue value = old->Get(i);
@ -2171,9 +2169,11 @@ JSHandle<TaggedArray> ObjectFactory::CopyArray(const JSHandle<TaggedArray> &old,
return newArray;
}
JSHandle<LayoutInfo> ObjectFactory::CreateLayoutInfo(int properties, MemSpaceType type, JSTaggedValue initVal)
JSHandle<LayoutInfo> ObjectFactory::CreateLayoutInfo(int properties, MemSpaceType type,
GrowMode mode, JSTaggedValue initVal)
{
uint32_t arrayLength = LayoutInfo::ComputeArrayLength(LayoutInfo::ComputeGrowCapacity(properties));
int growLength = mode == GrowMode::GROW ? LayoutInfo::ComputeGrowCapacity(properties) : properties;
uint32_t arrayLength = LayoutInfo::ComputeArrayLength(growLength);
JSHandle<LayoutInfo> layoutInfoHandle = JSHandle<LayoutInfo>::Cast(NewTaggedArray(arrayLength, initVal, type));
layoutInfoHandle->SetNumberOfElements(thread_, 0);
return layoutInfoHandle;
@ -2182,7 +2182,7 @@ JSHandle<LayoutInfo> ObjectFactory::CreateLayoutInfo(int properties, MemSpaceTyp
JSHandle<LayoutInfo> ObjectFactory::ExtendLayoutInfo(const JSHandle<LayoutInfo> &old, int properties,
JSTaggedValue initVal)
{
ASSERT(properties > old->NumberOfElements());
ASSERT(properties >= old->NumberOfElements());
uint32_t arrayLength = LayoutInfo::ComputeArrayLength(LayoutInfo::ComputeGrowCapacity(properties));
return JSHandle<LayoutInfo>(ExtendArray(JSHandle<TaggedArray>(old), arrayLength, initVal));
}
@ -3314,13 +3314,12 @@ JSHandle<TaggedArray> ObjectFactory::CopyDeque(const JSHandle<TaggedArray> &old,
auto header = heap_->AllocateYoungOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
JSHandle<TaggedArray> newArray(thread_, header);
newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength);
newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
uint32_t curIndex = first;
// newIndex use in new TaggedArray, 0 : New TaggedArray index
uint32_t newIndex = 0;
uint32_t oldCapacity = old->GetLength();
newArray->SetLength(newLength);
while (curIndex != last) {
JSTaggedValue value = old->Get(curIndex);
newArray->Set(thread_, newIndex, value);
@ -3353,8 +3352,7 @@ JSHandle<TaggedArray> ObjectFactory::CopyQueue(const JSHandle<TaggedArray> &old,
auto header = heap_->AllocateYoungOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
JSHandle<TaggedArray> newArray(thread_, header);
newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength);
newArray->SetLength(newLength);
newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
uint32_t curIndex = front;
// newIndex use in new TaggedArray, 0 : New TaggedArray index

View File

@ -172,6 +172,7 @@ using base::ErrorType;
using DeleteEntryPoint = void (*)(void *, void *);
enum class RemoveSlots { YES, NO };
enum class GrowMode { KEEP, GROW };
constexpr uint8_t INVALID_BUILTINS_ID = 0xFF;
@ -320,6 +321,7 @@ public:
const JSHandle<JSObject> &obj);
JSHandle<LayoutInfo> CreateLayoutInfo(int properties, MemSpaceType type = MemSpaceType::SEMI_SPACE,
GrowMode mode = GrowMode::GROW,
JSTaggedValue initVal = JSTaggedValue::Hole());
JSHandle<LayoutInfo> ExtendLayoutInfo(const JSHandle<LayoutInfo> &old, int properties,

View File

@ -321,7 +321,7 @@ DEF_RUNTIME_STUBS(UpdateLayOutAndAddTransition)
newHClassHandle->SetLayout(thread, layoutInfoHandle);
} else if (layoutInfoHandle->GetPropertiesCapacity() <= static_cast<int>(offset)) { // need to Grow
layoutInfoHandle.Update(
factory->ExtendLayoutInfo(layoutInfoHandle, LayoutInfo::ComputeGrowCapacity(offset)));
factory->ExtendLayoutInfo(layoutInfoHandle, offset));
newHClassHandle->SetLayout(thread, layoutInfoHandle);
}
layoutInfoHandle->AddKey(thread, offset, keyHandle.GetTaggedValue(), attrValue);

View File

@ -136,11 +136,11 @@ inline bool TaggedArray::HasDuplicateEntry() const
return false;
}
void TaggedArray::InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t length)
void TaggedArray::InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t length, uint32_t extraLength)
{
ASSERT(initValue.IsSpecial());
SetLength(length);
SetExtractLength(0);
SetExtraLength(extraLength);
for (uint32_t i = 0; i < length; i++) {
size_t offset = JSTaggedValue::TaggedTypeSize() * i;
Barriers::SetDynPrimitive<JSTaggedType>(GetData(), offset, initValue.GetRawData());

View File

@ -72,7 +72,7 @@ public:
static JSHandle<TaggedArray> SetCapacityInOldSpace(const JSThread *thread, const JSHandle<TaggedArray> &array,
uint32_t capa);
inline void InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t length);
inline void InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t length, uint32_t extraLength = 0);
static inline bool ShouldTrim(uint32_t oldLength, uint32_t newLength)
{
@ -82,7 +82,7 @@ public:
static constexpr size_t LENGTH_OFFSET = TaggedObjectSize();
ACCESSORS_PRIMITIVE_FIELD(Length, uint32_t, LENGTH_OFFSET, EXTRACT_LENGTH_OFFSET)
ACCESSORS_PRIMITIVE_FIELD(ExtractLength, uint32_t, EXTRACT_LENGTH_OFFSET, LAST_OFFSET)
ACCESSORS_PRIMITIVE_FIELD(ExtraLength, uint32_t, EXTRACT_LENGTH_OFFSET, LAST_OFFSET)
DEFINE_ALIGN_SIZE(LAST_OFFSET);
static constexpr size_t DATA_OFFSET = SIZE; // DATA_OFFSET equal to Empty Array size