diff --git a/runtime/class_linker/panda_file_translator.cpp b/runtime/class_linker/panda_file_translator.cpp index 08059cd080a68f0f0a33507f13f7c26bab9d296c..497ae35e364d4d2f19f445a8fbafdfe676782f01 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 9c7deea790a84f22ce8202a01ab1c323fa8ee7b9..5220bbb8ffb5d9255646f2843655da14994e2947 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 e19bcbe0698fb765515601e0e80687056e5ed155..cde5bb1ea0c36689d60c9fde9fe240bbab62cc56 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 f2e133eb01ec45790978f0dc2c352e82fd1813da..d4776de5baa02c79e34fffc8f52cbf3d17b29710 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 02f508e8b1bd539730e840254f7affde11007a14..7535fa71ab621ed75bdfc94319bc1a84b889b9a7 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 012b3d6add36e577745c16c4a5d302df9de62eaf..0cc0f2b1dbacff003ca133fa4d810f982e5e8d85 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 7bfbe547dd54af7c223ecf4e2ece75c916502124..f62dd72ff6f667767dcbe838a5d8f629026f4ed6 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 4527c4b34494f8e9e559e5b00a5677c8c6b146ce..149f967e38dfd340ea7c359b9e2fdfc326538064 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 c71c283fd76f4d04169275cd8f6284e25644d86a..0ffdaa8f039206474856fc3265dc96ec2fa221f5 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 20ea8a5a12d9791719fcde5d2e14a16c420309e6..f31d3e0082f15ec7438de4fd5e1efee234a093ca 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 fbb32dd2f87b26130d8aaaecda65d5e73a1e2450..855eea30edb227f3c79cdfa8600c83e140c155a5 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 5490ac660a3825c3381a4b0e894964cc0aae991c..f4ea20333c53b5c54240126cc8a7488e76d8b917 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;