From 376fd4b4693d632bc04713c1d2ba0f7b838ae7f5 Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 11 Aug 2022 12:23:28 +0300 Subject: [PATCH] made objects in GenerateProgram method allocated in non-movable space Signed-off-by: Malinin Andrey --- .../class_linker/panda_file_translator.cpp | 56 ++++++++------- runtime/ecma_string-inl.h | 17 +++-- runtime/ecma_string.h | 9 ++- runtime/ecma_string_table.cpp | 10 +-- runtime/ecma_string_table.h | 6 +- runtime/js_array.cpp | 9 +-- runtime/js_array.h | 6 +- runtime/js_object.cpp | 7 +- runtime/js_object.h | 3 +- runtime/literal_data_extractor.cpp | 16 +++-- runtime/object_factory.cpp | 72 ++++++++++++------- runtime/object_factory.h | 38 +++++----- 12 files changed, 150 insertions(+), 99 deletions(-) diff --git a/runtime/class_linker/panda_file_translator.cpp b/runtime/class_linker/panda_file_translator.cpp index 08059cd08..497ae35e3 100644 --- a/runtime/class_linker/panda_file_translator.cpp +++ b/runtime/class_linker/panda_file_translator.cpp @@ -164,7 +164,8 @@ Program *PandaFileTranslator::GenerateProgram(const panda_file::File &pf) EcmaHandleScope handleScope(thread_); JSHandle program = factory_->NewProgram(); - JSHandle location = factory_->NewFromStdStringUnCheck(pf.GetFilename(), true); + JSHandle location = + factory_->NewFromStdStringUnCheck(pf.GetFilename(), true, panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); // +1 for program JSHandle constpool = factory_->NewConstantPool(constpool_index_ + 1); @@ -183,8 +184,8 @@ Program *PandaFileTranslator::GenerateProgram(const panda_file::File &pf) if (value.GetConstpoolType() == ConstPoolType::STRING) { panda_file::File::EntityId id(it.first); auto foundStr = pf.GetStringData(id); - auto string = - factory_->GetRawStringFromStringTable(foundStr.data, foundStr.utf16_length, foundStr.is_ascii); + auto string = factory_->GetRawStringFromStringTable(foundStr.data, foundStr.utf16_length, foundStr.is_ascii, + panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); if (string == nullptr) { LOG(FATAL, ECMASCRIPT) << "Not enough memory"; } @@ -195,8 +196,8 @@ Program *PandaFileTranslator::GenerateProgram(const panda_file::File &pf) auto method = const_cast(FindMethods(it.first)); ASSERT(method != nullptr); - JSHandle js_func = - factory_->NewJSFunctionByDynClass(method, dynclass, FunctionKind::BASE_CONSTRUCTOR); + JSHandle js_func = factory_->NewJSFunctionByDynClass( + method, dynclass, FunctionKind::BASE_CONSTRUCTOR, panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); constpool->Set(thread_, value.GetConstpoolIndex(), js_func.GetTaggedValue()); js_func->SetConstantPool(thread_, constpool.GetTaggedValue()); } else if (value.GetConstpoolType() == ConstPoolType::NC_FUNCTION) { @@ -205,8 +206,8 @@ Program *PandaFileTranslator::GenerateProgram(const panda_file::File &pf) auto method = const_cast(FindMethods(it.first)); ASSERT(method != nullptr); - JSHandle js_func = - factory_->NewJSFunctionByDynClass(method, normalDynclass, FunctionKind::NORMAL_FUNCTION); + JSHandle js_func = factory_->NewJSFunctionByDynClass( + method, normalDynclass, FunctionKind::NORMAL_FUNCTION, panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); constpool->Set(thread_, value.GetConstpoolIndex(), js_func.GetTaggedValue()); js_func->SetConstantPool(thread_, constpool.GetTaggedValue()); } else if (value.GetConstpoolType() == ConstPoolType::GENERATOR_FUNCTION) { @@ -216,13 +217,14 @@ Program *PandaFileTranslator::GenerateProgram(const panda_file::File &pf) ASSERT(method != nullptr); JSHandle js_func = - factory_->NewJSFunctionByDynClass(method, generatorDynclass, FunctionKind::GENERATOR_FUNCTION); + factory_->NewJSFunctionByDynClass(method, generatorDynclass, FunctionKind::GENERATOR_FUNCTION, + panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); // 26.3.4.3 prototype // Whenever a GeneratorFunction instance is created another ordinary object is also created and // is the initial value of the generator function's "prototype" property. JSHandle obj_fun = env->GetObjectFunction(); - JSHandle initial_generator_func_prototype = - factory_->NewJSObjectByConstructor(JSHandle(obj_fun), obj_fun); + JSHandle initial_generator_func_prototype = factory_->NewJSObjectByConstructor( + JSHandle(obj_fun), obj_fun, panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); JSObject::SetPrototype(thread_, initial_generator_func_prototype, env->GetGeneratorPrototype()); js_func->SetProtoOrDynClass(thread_, initial_generator_func_prototype); @@ -234,8 +236,8 @@ Program *PandaFileTranslator::GenerateProgram(const panda_file::File &pf) auto method = const_cast(FindMethods(it.first)); ASSERT(method != nullptr); - JSHandle js_func = - factory_->NewJSFunctionByDynClass(method, asyncDynclass, FunctionKind::ASYNC_FUNCTION); + JSHandle js_func = factory_->NewJSFunctionByDynClass( + method, asyncDynclass, FunctionKind::ASYNC_FUNCTION, panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); constpool->Set(thread_, value.GetConstpoolIndex(), js_func.GetTaggedValue()); js_func->SetConstantPool(thread_, constpool.GetTaggedValue()); } else if (value.GetConstpoolType() == ConstPoolType::ASYNC_GENERATOR_FUNCTION) { @@ -244,8 +246,9 @@ Program *PandaFileTranslator::GenerateProgram(const panda_file::File &pf) auto method = const_cast(FindMethods(it.first)); ASSERT(method != nullptr); - JSHandle js_func = factory_->NewJSFunctionByDynClass(method, asyncgeneratorDynclass, - FunctionKind::ASYNC_GENERATOR_FUNCTION); + JSHandle js_func = factory_->NewJSFunctionByDynClass( + method, asyncgeneratorDynclass, FunctionKind::ASYNC_GENERATOR_FUNCTION, + panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); constpool->Set(thread_, value.GetConstpoolIndex(), js_func.GetTaggedValue()); js_func->SetConstantPool(thread_, constpool.GetTaggedValue()); } else if (value.GetConstpoolType() == ConstPoolType::CLASS_FUNCTION) { @@ -261,8 +264,8 @@ Program *PandaFileTranslator::GenerateProgram(const panda_file::File &pf) auto method = const_cast(FindMethods(it.first)); ASSERT(method != nullptr); - JSHandle js_func = - factory_->NewJSFunctionByDynClass(method, normalDynclass, FunctionKind::NORMAL_FUNCTION); + JSHandle js_func = factory_->NewJSFunctionByDynClass( + method, normalDynclass, FunctionKind::NORMAL_FUNCTION, panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); constpool->Set(thread_, value.GetConstpoolIndex(), js_func.GetTaggedValue()); js_func->SetConstantPool(thread_, constpool.GetTaggedValue()); } else if (value.GetConstpoolType() == ConstPoolType::OBJECT_LITERAL) { @@ -270,7 +273,8 @@ Program *PandaFileTranslator::GenerateProgram(const panda_file::File &pf) JSMutableHandle elements(thread_, JSTaggedValue::Undefined()); JSMutableHandle properties(thread_, JSTaggedValue::Undefined()); LiteralDataExtractor::ExtractObjectDatas(thread_, &pf, index, elements, properties, this); - JSHandle obj = JSObject::CreateObjectFromProperties(thread_, properties); + JSHandle obj = JSObject::CreateObjectFromProperties( + thread_, properties, panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); JSMutableHandle key(thread_, JSTaggedValue::Undefined()); JSMutableHandle valueHandle(thread_, JSTaggedValue::Undefined()); @@ -290,7 +294,8 @@ Program *PandaFileTranslator::GenerateProgram(const panda_file::File &pf) LiteralDataExtractor::GetDatasIgnoreType(thread_, &pf, static_cast(index)); uint32_t length = literal->GetLength(); - JSHandle arr(JSArray::ArrayCreate(thread_, JSTaggedNumber(length))); + JSHandle arr( + JSArray::ArrayCreate(thread_, JSTaggedNumber(length), panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT)); arr->SetElements(thread_, literal); constpool->Set(thread_, value.GetConstpoolIndex(), arr.GetTaggedValue()); } else if (value.GetConstpoolType() == ConstPoolType::TAGGED_ARRAY) { @@ -303,8 +308,8 @@ Program *PandaFileTranslator::GenerateProgram(const panda_file::File &pf) { auto method = const_cast(FindMethods(main_method_index_)); ASSERT(method != nullptr); - JSHandle mainFunc = - factory_->NewJSFunctionByDynClass(method, dynclass, FunctionKind::BASE_CONSTRUCTOR); + JSHandle mainFunc = factory_->NewJSFunctionByDynClass( + method, dynclass, FunctionKind::BASE_CONSTRUCTOR, panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); mainFunc->SetConstantPool(thread_, constpool.GetTaggedValue()); program->SetMainFunction(thread_, mainFunc.GetTaggedValue()); program->SetMethodsData(methods_.release()); @@ -574,18 +579,19 @@ JSHandle PandaFileTranslator::DefineMethodInLiteral(uint32_t method_ } else { function_class = JSHandle::Cast(env->GetGeneratorFunctionClass()); } - JSHandle js_func = factory_->NewJSFunctionByDynClass(method, function_class, kind); + JSHandle js_func = factory_->NewJSFunctionByDynClass(method, function_class, kind, + panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); if (kind == FunctionKind::GENERATOR_FUNCTION) { JSHandle obj_fun = env->GetObjectFunction(); - JSHandle initial_generator_func_prototype = - factory_->NewJSObjectByConstructor(JSHandle(obj_fun), obj_fun); + JSHandle initial_generator_func_prototype = factory_->NewJSObjectByConstructor( + JSHandle(obj_fun), obj_fun, panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); JSObject::SetPrototype(thread_, initial_generator_func_prototype, env->GetGeneratorPrototype()); js_func->SetProtoOrDynClass(thread_, initial_generator_func_prototype); } else if (kind == FunctionKind::ASYNC_GENERATOR_FUNCTION) { JSHandle obj_fun = env->GetObjectFunction(); - JSHandle initial_async_generator_func_prototype = - factory_->NewJSObjectByConstructor(JSHandle(obj_fun), obj_fun); + JSHandle initial_async_generator_func_prototype = factory_->NewJSObjectByConstructor( + JSHandle(obj_fun), obj_fun, panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); JSObject::SetPrototype(thread_, initial_async_generator_func_prototype, env->GetAsyncGeneratorPrototype()); js_func->SetProtoOrDynClass(thread_, initial_async_generator_func_prototype); } diff --git a/runtime/ecma_string-inl.h b/runtime/ecma_string-inl.h index 9c7deea79..5220bbb8f 100644 --- a/runtime/ecma_string-inl.h +++ b/runtime/ecma_string-inl.h @@ -48,14 +48,14 @@ inline EcmaString *EcmaString::CreateEmptyString(const EcmaVM *vm) /* static */ inline EcmaString *EcmaString::CreateFromUtf8(const uint8_t *utf8_data, uint32_t utf8_len, const EcmaVM *vm, - bool can_be_compress) + bool can_be_compress, panda::SpaceType space_type) { if (utf8_len == 0) { return vm->GetFactory()->GetEmptyString().GetObject(); } EcmaString *string = nullptr; if (can_be_compress) { - string = AllocStringObject(utf8_len, true, vm); + string = AllocStringObject(utf8_len, true, vm, space_type); ASSERT(string != nullptr); if (memcpy_s(string->GetDataUtf8Writable(), utf8_len, utf8_data, utf8_len) != EOK) { @@ -64,7 +64,7 @@ inline EcmaString *EcmaString::CreateFromUtf8(const uint8_t *utf8_data, uint32_t } } else { auto utf16_len = base::utf_helper::Utf8ToUtf16Size(utf8_data, utf8_len); - string = AllocStringObject(utf16_len, false, vm); + string = AllocStringObject(utf16_len, false, vm, space_type); ASSERT(string != nullptr); [[maybe_unused]] auto len = base::utf_helper::ConvertRegionUtf8ToUtf16( @@ -76,12 +76,12 @@ inline EcmaString *EcmaString::CreateFromUtf8(const uint8_t *utf8_data, uint32_t } inline EcmaString *EcmaString::CreateFromUtf16(const uint16_t *utf16_data, uint32_t utf16_len, const EcmaVM *vm, - bool can_be_compress) + bool can_be_compress, panda::SpaceType space_type) { if (utf16_len == 0) { return vm->GetFactory()->GetEmptyString().GetObject(); } - auto string = AllocStringObject(utf16_len, can_be_compress, vm); + auto string = AllocStringObject(utf16_len, can_be_compress, vm, space_type); ASSERT(string != nullptr); if (can_be_compress) { @@ -115,10 +115,13 @@ inline uint16_t EcmaString::At(int32_t index) const } /* static */ -inline EcmaString *EcmaString::AllocStringObject(size_t length, bool compressed, const EcmaVM *vm) +inline EcmaString *EcmaString::AllocStringObject(size_t length, bool compressed, const EcmaVM *vm, + panda::SpaceType space_type) { size_t size = compressed ? ComputeSizeUtf8(length) : ComputeSizeUtf16(length); - auto string = reinterpret_cast(vm->GetFactory()->AllocStringObject(size)); + auto string = space_type == panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT + ? reinterpret_cast(vm->GetFactory()->AllocNonMovableStringObject(size)) + : reinterpret_cast(vm->GetFactory()->AllocStringObject(size)); string->SetLength(length, compressed); string->SetRawHashcode(0); return reinterpret_cast(string); diff --git a/runtime/ecma_string.h b/runtime/ecma_string.h index e19bcbe06..cde5bb1ea 100644 --- a/runtime/ecma_string.h +++ b/runtime/ecma_string.h @@ -54,9 +54,11 @@ public: static EcmaString *CreateEmptyString(const EcmaVM *vm); static EcmaString *CreateFromUtf8(const uint8_t *utf8_data, uint32_t utf8_len, const EcmaVM *vm, - bool can_be_compress); + bool can_be_compress, + panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT); static EcmaString *CreateFromUtf16(const uint16_t *utf16_data, uint32_t utf16_len, const EcmaVM *vm, - bool can_be_compress); + bool can_be_compress, + panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT); static EcmaString *Concat(const JSHandle &str1_handle, const JSHandle &str2_handle, const EcmaVM *vm); static EcmaString *FastSubString(const JSHandle &src, uint32_t start, uint32_t utf16_len, @@ -272,7 +274,8 @@ public: return compressed_strings_enabled_; } - static EcmaString *AllocStringObject(size_t length, bool compressed, const EcmaVM *vm); + static EcmaString *AllocStringObject(size_t length, bool compressed, const EcmaVM *vm, + panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT); static bool CanBeCompressed(const uint8_t *utf8_data, uint32_t utf8_len); static bool CanBeCompressed(const uint16_t *utf16_data, uint32_t utf16_len); diff --git a/runtime/ecma_string_table.cpp b/runtime/ecma_string_table.cpp index f2e133eb0..d4776de5b 100644 --- a/runtime/ecma_string_table.cpp +++ b/runtime/ecma_string_table.cpp @@ -90,26 +90,28 @@ void EcmaStringTable::InternEmptyString(EcmaString *empty_str) InternString(empty_str); } -EcmaString *EcmaStringTable::GetOrInternString(const uint8_t *utf8_data, uint32_t utf8_len, bool can_be_compress) +EcmaString *EcmaStringTable::GetOrInternString(const uint8_t *utf8_data, uint32_t utf8_len, bool can_be_compress, + panda::SpaceType space_type) { EcmaString *result = GetString(utf8_data, utf8_len, can_be_compress); if (result != nullptr) { return result; } - result = EcmaString::CreateFromUtf8(utf8_data, utf8_len, vm_, can_be_compress); + result = EcmaString::CreateFromUtf8(utf8_data, utf8_len, vm_, can_be_compress, space_type); InternString(result); return result; } -EcmaString *EcmaStringTable::GetOrInternString(const uint16_t *utf16_data, uint32_t utf16_len, bool can_be_compress) +EcmaString *EcmaStringTable::GetOrInternString(const uint16_t *utf16_data, uint32_t utf16_len, bool can_be_compress, + panda::SpaceType space_type) { EcmaString *result = GetString(utf16_data, utf16_len); if (result != nullptr) { return result; } - result = EcmaString::CreateFromUtf16(utf16_data, utf16_len, vm_, can_be_compress); + result = EcmaString::CreateFromUtf16(utf16_data, utf16_len, vm_, can_be_compress, space_type); InternString(result); return result; } diff --git a/runtime/ecma_string_table.h b/runtime/ecma_string_table.h index 02f508e8b..7535fa71a 100644 --- a/runtime/ecma_string_table.h +++ b/runtime/ecma_string_table.h @@ -34,8 +34,10 @@ public: } void InternEmptyString(EcmaString *empty_str); - EcmaString *GetOrInternString(const uint8_t *utf8_data, uint32_t utf8_len, bool can_be_compress); - EcmaString *GetOrInternString(const uint16_t *utf16_data, uint32_t utf16_len, bool can_be_compress); + EcmaString *GetOrInternString(const uint8_t *utf8_data, uint32_t utf8_len, bool can_be_compress, + panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT); + EcmaString *GetOrInternString(const uint16_t *utf16_data, uint32_t utf16_len, bool can_be_compress, + panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT); EcmaString *GetOrInternString(EcmaString *string); void SweepWeakReference(const WeakRootVisitor &visitor); diff --git a/runtime/js_array.cpp b/runtime/js_array.cpp index 012b3d6ad..0cc0f2b1d 100644 --- a/runtime/js_array.cpp +++ b/runtime/js_array.cpp @@ -49,16 +49,16 @@ bool JSArray::LengthSetter(JSThread *thread, const JSHandle &self, con return true; } -JSHandle JSArray::ArrayCreate(JSThread *thread, JSTaggedNumber length) +JSHandle JSArray::ArrayCreate(JSThread *thread, JSTaggedNumber length, panda::SpaceType space_type) { JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle arrayFunction = env->GetArrayFunction(); - return JSArray::ArrayCreate(thread, length, arrayFunction); + return JSArray::ArrayCreate(thread, length, arrayFunction, space_type); } // 9.4.2.2 ArrayCreate(length, proto) JSHandle JSArray::ArrayCreate(JSThread *thread, JSTaggedNumber length, - const JSHandle &new_target) + const JSHandle &new_target, panda::SpaceType space_type) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // Assert: length is an integer Number ≥ 0. @@ -74,7 +74,8 @@ JSHandle JSArray::ArrayCreate(JSThread *thread, JSTaggedNumber le // 8. Set the [[Prototype]] internal slot of A to proto. JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle array_func = env->GetArrayFunction(); - JSHandle obj = factory->NewJSObjectByConstructor(JSHandle(array_func), new_target); + JSHandle obj = + factory->NewJSObjectByConstructor(JSHandle(array_func), new_target, space_type); // 9. Set the [[Extensible]] internal slot of A to true. obj->GetJSHClass()->SetExtensible(true); diff --git a/runtime/js_array.h b/runtime/js_array.h index 7bfbe547d..f62dd72ff 100644 --- a/runtime/js_array.h +++ b/runtime/js_array.h @@ -30,9 +30,11 @@ public: CAST_CHECK(JSArray, IsJSArray); - static JSHandle ArrayCreate(JSThread *thread, JSTaggedNumber length); static JSHandle ArrayCreate(JSThread *thread, JSTaggedNumber length, - const JSHandle &new_target); + panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT); + static JSHandle ArrayCreate(JSThread *thread, JSTaggedNumber length, + const JSHandle &new_target, + panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT); static JSTaggedValue ArraySpeciesCreate(JSThread *thread, const JSHandle &original_array, JSTaggedNumber length); static bool ArraySetLength(JSThread *thread, const JSHandle &array, const PropertyDescriptor &desc); diff --git a/runtime/js_object.cpp b/runtime/js_object.cpp index 4527c4b34..149f967e3 100644 --- a/runtime/js_object.cpp +++ b/runtime/js_object.cpp @@ -1818,7 +1818,8 @@ void JSObject::DefineGetter(JSThread *thread, const JSHandle &obj op.DefineGetter(value); } -JSHandle JSObject::CreateObjectFromProperties(const JSThread *thread, const JSHandle &properties) +JSHandle JSObject::CreateObjectFromProperties(const JSThread *thread, const JSHandle &properties, + panda::SpaceType space_type) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); size_t length = properties->GetLength(); @@ -1830,7 +1831,7 @@ JSHandle JSObject::CreateObjectFromProperties(const JSThread *thread, propsLen++; } if (propsLen <= PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES) { - JSHandle obj = factory->NewJSObjectByClass(properties, propsLen); + JSHandle obj = factory->NewJSObjectByClass(properties, propsLen, space_type); ASSERT_PRINT(obj->IsECMAObject(), "Obj is not a valid object"); for (size_t i = 0; i < propsLen; i++) { // 2: literal contains a pair of key-value @@ -1838,7 +1839,7 @@ JSHandle JSObject::CreateObjectFromProperties(const JSThread *thread, } return obj; } - JSHandle obj = factory->NewEmptyJSObject(); + JSHandle obj = factory->NewEmptyJSObject(space_type); JSHandle jshclass(thread, obj->GetJSHClass()); uint32_t numberInlinedProps = jshclass->GetInlinedProperties(); JSHClass::TransitionToDictionary(thread, obj); diff --git a/runtime/js_object.h b/runtime/js_object.h index c71c283fd..0ffdaa8f0 100644 --- a/runtime/js_object.h +++ b/runtime/js_object.h @@ -551,7 +551,8 @@ public: static void DefineGetter(JSThread *thread, const JSHandle &obj, const JSHandle &key, const JSHandle &value); static JSHandle CreateObjectFromProperties(const JSThread *thread, - const JSHandle &properties); + const JSHandle &properties, + panda::SpaceType space_type); static void GetAllKeys(const JSThread *thread, const JSHandle &obj, int offset, const JSHandle &key_array); static void GetAllKeys(const JSThread *thread, const JSHandle &obj, diff --git a/runtime/literal_data_extractor.cpp b/runtime/literal_data_extractor.cpp index 20ea8a5a1..f31d3e008 100644 --- a/runtime/literal_data_extractor.cpp +++ b/runtime/literal_data_extractor.cpp @@ -38,8 +38,11 @@ void LiteralDataExtractor::ExtractObjectDatas(JSThread *thread, const panda_file panda_file::LiteralDataAccessor lda(*pf, literalArraysId); uint32_t num = lda.GetLiteralValsNum(index) / 2; // 2: half - elements.Update(factory->NewTaggedArray(num).GetTaggedValue()); - properties.Update(factory->NewTaggedArray(num).GetTaggedValue()); + elements.Update(factory->NewTaggedArray(num, JSTaggedValue::Hole(), panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT) + .GetTaggedValue()); + properties.Update( + factory->NewTaggedArray(num, JSTaggedValue::Hole(), panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT) + .GetTaggedValue()); uint32_t epos = 0; uint32_t ppos = 0; const uint8_t pairSize = 2; @@ -100,7 +103,8 @@ void LiteralDataExtractor::ExtractObjectDatas(JSThread *thread, const panda_file break; } case LiteralTag::ACCESSOR: { - JSHandle accessor = factory->NewAccessorData(); + JSHandle accessor = + factory->NewAccessorData(panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); jt = JSTaggedValue(accessor.GetTaggedValue()); break; } @@ -130,7 +134,8 @@ JSHandle LiteralDataExtractor::GetDatasIgnoreType(JSThread *thread, panda_file::LiteralDataAccessor lda(*pf, literalArraysId); uint32_t num = lda.GetLiteralValsNum(index) / 2; // 2: half - JSHandle literals = factory->NewTaggedArray(num); + JSHandle literals = + factory->NewTaggedArray(num, JSTaggedValue::Hole(), panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); uint32_t pos = 0; lda.EnumerateLiteralVals(index, [literals, &pos, factory, thread, pft, pf](const panda_file::LiteralDataAccessor::LiteralValue &value, @@ -185,7 +190,8 @@ JSHandle LiteralDataExtractor::GetDatasIgnoreType(JSThread *thread, break; } case LiteralTag::ACCESSOR: { - JSHandle accessor = factory->NewAccessorData(); + JSHandle accessor = + factory->NewAccessorData(panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT); jt = accessor.GetTaggedValue(); break; } diff --git a/runtime/object_factory.cpp b/runtime/object_factory.cpp index fbb32dd2f..855eea30e 100644 --- a/runtime/object_factory.cpp +++ b/runtime/object_factory.cpp @@ -731,7 +731,8 @@ JSHandle ObjectFactory::NewJSError(const ErrorType &error_type, const } JSHandle ObjectFactory::NewJSObjectByConstructor(const JSHandle &constructor, - const JSHandle &new_target) + const JSHandle &new_target, + panda::SpaceType space_type) { JSHandle jshclass; if (!constructor->HasFunctionPrototype() || @@ -744,7 +745,9 @@ JSHandle ObjectFactory::NewJSObjectByConstructor(const JSHandle obj = NewJSObject(jshclass); + JSHandle obj = space_type == panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT + ? NewNonMovableJSObject(jshclass) + : NewJSObject(jshclass); { JSType type = jshclass->GetObjectType(); switch (type) { @@ -1066,9 +1069,11 @@ JSHandle ObjectFactory::CreateFunctionClass(FunctionKind kind, uint32_ } JSHandle ObjectFactory::NewJSFunctionByDynClass(JSMethod *method, const JSHandle &clazz, - FunctionKind kind) + FunctionKind kind, panda::SpaceType space_type) { - JSHandle function = JSHandle::Cast(NewJSObject(clazz)); + JSHandle function = space_type == panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT + ? JSHandle::Cast(NewNonMovableJSObject(clazz)) + : JSHandle::Cast(NewJSObject(clazz)); ASSERT(clazz->IsCallable()); ASSERT(clazz->IsExtensible()); JSFunction::InitializeJSFunction(thread_, function, kind); @@ -1383,7 +1388,7 @@ JSHandle ObjectFactory::NewLexicalEnv(int num_slots) { NewObjectHook(); size_t size = LexicalEnv::ComputeSize(num_slots); - auto header = heap_helper_.AllocateYoungGenerationOrHugeObject(env_class_, size); + auto header = heap_helper_.AllocateNonMovableOrHugeObject(env_class_, size); JSHandle array(thread_, header); array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), num_slots + LexicalEnv::RESERVED_ENV_LENGTH); return array; @@ -1487,10 +1492,12 @@ JSHandle ObjectFactory::NewSymbolWithTableWithChar(const char *descrip return NewSymbolWithTable(JSHandle(string)); } -JSHandle ObjectFactory::NewAccessorData() +JSHandle ObjectFactory::NewAccessorData(panda::SpaceType space_type) { NewObjectHook(); - TaggedObject *header = heap_helper_.AllocateYoungGenerationOrHugeObject(accessor_data_class_); + TaggedObject *header = space_type == panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT + ? heap_helper_.AllocateNonMovableOrHugeObject(accessor_data_class_) + : heap_helper_.AllocateYoungGenerationOrHugeObject(accessor_data_class_); JSHandle acc(thread_, AccessorData::Cast(header)); acc->SetGetter(thread_, JSTaggedValue::Undefined()); acc->SetSetter(thread_, JSTaggedValue::Undefined()); @@ -1646,7 +1653,8 @@ JSHandle ObjectFactory::NewEmptyArray(bool weak) return array; } -JSHandle ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedValue init_val, bool non_movable) +JSHandle ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedValue init_val, + panda::SpaceType space_type) { NewObjectHook(); if (length == 0) { @@ -1655,7 +1663,7 @@ JSHandle ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedVal size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length); TaggedObject *header = nullptr; - if (non_movable) { + if (space_type == panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT) { header = heap_helper_.AllocateNonMovableOrHugeObject(array_class_, size); } else { header = heap_helper_.AllocateYoungGenerationOrHugeObject(array_class_, size); @@ -1899,25 +1907,27 @@ JSHandle ObjectFactory::NewObjectWrapper(const JSHandle ObjectFactory::GetStringFromStringTable(const uint8_t *utf8_data, uint32_t utf8_len, - bool can_be_compress) const + bool can_be_compress, panda::SpaceType space_type) const { NewObjectHook(); if (utf8_len == 0) { return GetEmptyString(); } auto stringTable = vm_->GetEcmaStringTable(); - return JSHandle(thread_, stringTable->GetOrInternString(utf8_data, utf8_len, can_be_compress)); + return JSHandle(thread_, + stringTable->GetOrInternString(utf8_data, utf8_len, can_be_compress, space_type)); } JSHandle ObjectFactory::GetStringFromStringTable(const uint16_t *utf16_data, uint32_t utf16_len, - bool can_be_compress) const + bool can_be_compress, panda::SpaceType space_type) const { NewObjectHook(); if (utf16_len == 0) { return GetEmptyString(); } auto stringTable = vm_->GetEcmaStringTable(); - return JSHandle(thread_, stringTable->GetOrInternString(utf16_data, utf16_len, can_be_compress)); + return JSHandle(thread_, + stringTable->GetOrInternString(utf16_data, utf16_len, can_be_compress, space_type)); } JSHandle ObjectFactory::GetStringFromStringTable(EcmaString *string) const @@ -1932,7 +1942,7 @@ JSHandle ObjectFactory::GetStringFromStringTable(EcmaString *string) // NB! don't do special case for C0 80, it means '\u0000', so don't convert to UTF-8 EcmaString *ObjectFactory::GetRawStringFromStringTable(const uint8_t *mutf8_data, uint32_t utf16_len, - bool can_be_compressed) const + bool can_be_compressed, panda::SpaceType space_type) const { NewObjectHook(); if (UNLIKELY(utf16_len == 0)) { @@ -1940,12 +1950,12 @@ EcmaString *ObjectFactory::GetRawStringFromStringTable(const uint8_t *mutf8_data } if (can_be_compressed) { - return EcmaString::Cast(vm_->GetEcmaStringTable()->GetOrInternString(mutf8_data, utf16_len, true)); + return EcmaString::Cast(vm_->GetEcmaStringTable()->GetOrInternString(mutf8_data, utf16_len, true, space_type)); } PandaVector utf16_data(utf16_len); auto len = utf::ConvertRegionMUtf8ToUtf16(mutf8_data, utf16_data.data(), utf::Mutf8Size(mutf8_data), utf16_len, 0); - return EcmaString::Cast(vm_->GetEcmaStringTable()->GetOrInternString(utf16_data.data(), len, false)); + return EcmaString::Cast(vm_->GetEcmaStringTable()->GetOrInternString(utf16_data.data(), len, false, space_type)); } JSHandle ObjectFactory::NewPropertyBox(const JSHandle &value) @@ -2222,18 +2232,21 @@ JSHandle ObjectFactory::CreateObjectClass(const JSHandle return objClass; } -JSHandle ObjectFactory::NewJSObjectByClass(const JSHandle &properties, size_t length) +JSHandle ObjectFactory::NewJSObjectByClass(const JSHandle &properties, size_t length, + panda::SpaceType space_type) { JSHandle dynclass = CreateObjectClass(properties, length); - JSHandle obj = NewJSObject(dynclass); + JSHandle obj = space_type == panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT + ? NewNonMovableJSObject(dynclass) + : NewJSObject(dynclass); return obj; } -JSHandle ObjectFactory::NewEmptyJSObject() +JSHandle ObjectFactory::NewEmptyJSObject(panda::SpaceType space_type) { JSHandle env = vm_->GetGlobalEnv(); JSHandle builtinObj = env->GetObjectFunction(); - return NewJSObjectByConstructor(JSHandle(builtinObj), builtinObj); + return NewJSObjectByConstructor(JSHandle(builtinObj), builtinObj, space_type); } EcmaString *ObjectFactory::ResolveString(uint32_t string_id) @@ -2249,7 +2262,7 @@ EcmaString *ObjectFactory::ResolveString(uint32_t string_id) JSHandle ObjectFactory::NewClassInfoExtractor(JSMethod *ctor_method) { NewObjectHook(); - TaggedObject *header = heap_helper_.AllocateYoungGenerationOrHugeObject(class_info_extractor_h_class_); + TaggedObject *header = heap_helper_.AllocateNonMovableOrHugeObject(class_info_extractor_h_class_); JSHandle obj(thread_, header); obj->InitializeBitField(); obj->SetConstructorMethod(ctor_method); @@ -2287,10 +2300,11 @@ JSHandle ObjectFactory::NewFromStdString(const std::string &data) return GetStringFromStringTable(utf8_data, data.size(), can_be_compress); } -JSHandle ObjectFactory::NewFromStdStringUnCheck(const std::string &data, bool can_be_compress) +JSHandle ObjectFactory::NewFromStdStringUnCheck(const std::string &data, bool can_be_compress, + panda::SpaceType space_type) { auto utf8_data = reinterpret_cast(data.c_str()); - return GetStringFromStringTable(utf8_data, data.size(), can_be_compress); + return GetStringFromStringTable(utf8_data, data.size(), can_be_compress, space_type); } JSHandle ObjectFactory::NewFromUtf8(const uint8_t *utf8_data, uint32_t utf8_len) @@ -2321,28 +2335,32 @@ JSHandle ObjectFactory::NewFromUtf8Literal(const uint8_t *utf8_data, { NewObjectHook(); bool can_be_compress = EcmaString::CanBeCompressed(utf8_data, utf8_len); - return JSHandle(thread_, EcmaString::CreateFromUtf8(utf8_data, utf8_len, vm_, can_be_compress)); + return JSHandle(thread_, EcmaString::CreateFromUtf8(utf8_data, utf8_len, vm_, can_be_compress, + panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT)); } JSHandle ObjectFactory::NewFromUtf8LiteralUnCheck(const uint8_t *utf8_data, uint32_t utf8_len, bool can_be_compress) { NewObjectHook(); - return JSHandle(thread_, EcmaString::CreateFromUtf8(utf8_data, utf8_len, vm_, can_be_compress)); + return JSHandle(thread_, EcmaString::CreateFromUtf8(utf8_data, utf8_len, vm_, can_be_compress, + panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT)); } JSHandle ObjectFactory::NewFromUtf16Literal(const uint16_t *utf16_data, uint32_t utf16_len) { NewObjectHook(); bool can_be_compress = EcmaString::CanBeCompressed(utf16_data, utf16_len); - return JSHandle(thread_, EcmaString::CreateFromUtf16(utf16_data, utf16_len, vm_, can_be_compress)); + return JSHandle(thread_, EcmaString::CreateFromUtf16(utf16_data, utf16_len, vm_, can_be_compress, + panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT)); } JSHandle ObjectFactory::NewFromUtf16LiteralUnCheck(const uint16_t *utf16_data, uint32_t utf16_len, bool can_be_compress) { NewObjectHook(); - return JSHandle(thread_, EcmaString::CreateFromUtf16(utf16_data, utf16_len, vm_, can_be_compress)); + return JSHandle(thread_, EcmaString::CreateFromUtf16(utf16_data, utf16_len, vm_, can_be_compress, + panda::SpaceType::SPACE_TYPE_NON_MOVABLE_OBJECT)); } JSHandle ObjectFactory::NewFromString(EcmaString *str) diff --git a/runtime/object_factory.h b/runtime/object_factory.h index 5490ac660..f4ea20333 100644 --- a/runtime/object_factory.h +++ b/runtime/object_factory.h @@ -127,7 +127,7 @@ public: JSHandle NewPrototypeHandler(); - JSHandle NewEmptyJSObject(); + JSHandle NewEmptyJSObject(panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT); // use for others create, prototype is Function.prototype // use for native function @@ -201,7 +201,7 @@ public: JSHandle NewSymbolWithTableWithChar(const char *description); - JSHandle NewAccessorData(); + JSHandle NewAccessorData(panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT); JSHandle NewInternalAccessor(void *setter, void *getter); JSHandle NewPromiseCapability(); @@ -234,7 +234,7 @@ public: JSHandle NewJSString(const JSHandle &str); JSHandle NewTaggedArray(uint32_t length, JSTaggedValue init_val = JSTaggedValue::Hole()); - JSHandle NewTaggedArray(uint32_t length, JSTaggedValue init_val, bool non_movable); + JSHandle NewTaggedArray(uint32_t length, JSTaggedValue init_val, panda::SpaceType space_type); JSHandle NewWeakTaggedArray(uint32_t length, JSTaggedValue init_val = JSTaggedValue::Hole()); JSHandle NewDictionaryArray(uint32_t length); @@ -337,11 +337,13 @@ public: const DeleteEntryPoint &call_back = nullptr, void *data = nullptr, bool non_movable = false); - JSHandle NewJSObjectByClass(const JSHandle &properties, size_t length); + JSHandle NewJSObjectByClass(const JSHandle &properties, size_t length, + panda::SpaceType space_type); // only use for creating Function.prototype and Function JSHandle NewJSFunctionByDynClass(JSMethod *method, const JSHandle &clazz, - FunctionKind kind = FunctionKind::NORMAL_FUNCTION); + FunctionKind kind = FunctionKind::NORMAL_FUNCTION, + panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT); EcmaString *ResolveString(uint32_t string_id); void ObtainRootClass(const JSHandle &global_env); @@ -353,7 +355,8 @@ public: // used for creating jsobject by constructor JSHandle NewJSObjectByConstructor(const JSHandle &constructor, - const JSHandle &new_target); + const JSHandle &new_target, + panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT); JSHandle NewClassInfoExtractor(JSMethod *ctor_method); @@ -364,7 +367,8 @@ public: JSHandle NewFromCanBeCompressString(const PandaString &data); JSHandle NewFromStdString(const std::string &data); - JSHandle NewFromStdStringUnCheck(const std::string &data, bool can_be_compress); + JSHandle NewFromStdStringUnCheck(const std::string &data, bool can_be_compress, + panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT); JSHandle NewFromUtf8(const uint8_t *utf8_data, uint32_t utf8_len); JSHandle NewFromUtf8UnCheck(const uint8_t *utf8_data, uint32_t utf8_len, bool can_be_compress); @@ -385,6 +389,9 @@ public: // used for creating Function JSHandle NewJSObject(const JSHandle &jshclass); + // used to create nonmovable js_object + JSHandle NewNonMovableJSObject(const JSHandle &jshclass); + // used for creating jshclass in GlobalEnv, EcmaVM template inline JSHandle CreateDynClass(JSHClass *hclass, JSType type, uint32_t flags = 0, @@ -500,9 +507,6 @@ private: // used for creating jshclass in GlobalEnv, EcmaVM JSHandle NewEcmaDynClassClass(JSHClass *hclass, uint32_t size, JSType type); - // used to create nonmovable js_object - JSHandle NewNonMovableJSObject(const JSHandle &jshclass); - // used for creating Function JSHandle NewJSFunction(const JSHandle &env, const JSHandle &dyn_klass); JSHandle CreateObjectClass(const JSHandle &properties, size_t length); @@ -520,14 +524,16 @@ private: JSHandle NewJSPrimitiveRef(const JSHandle &dyn_klass, const JSHandle &object); - JSHandle GetStringFromStringTable(const uint8_t *utf8_data, uint32_t utf8_len, - bool can_be_compress) const; + JSHandle GetStringFromStringTable( + const uint8_t *utf8_data, uint32_t utf8_len, bool can_be_compress, + panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT) const; // For MUtf-8 string data - EcmaString *GetRawStringFromStringTable(const uint8_t *mutf8_data, uint32_t utf16_len, - bool can_be_compressed) const; + EcmaString *GetRawStringFromStringTable(const uint8_t *mutf8_data, uint32_t utf16_len, bool can_be_compressed, + panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT) const; - JSHandle GetStringFromStringTable(const uint16_t *utf16_data, uint32_t utf16_len, - bool can_be_compress) const; + JSHandle GetStringFromStringTable( + const uint16_t *utf16_data, uint32_t utf16_len, bool can_be_compress, + panda::SpaceType space_type = panda::SpaceType::SPACE_TYPE_OBJECT) const; JSHandle GetStringFromStringTable(EcmaString *string) const; -- Gitee