diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 162776eace67afacc91ea83529c198650d1c8967..a662fbb63464c8dbc9c1321f063244531a448623 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -104,13 +104,6 @@ set(ECMASCRIPT_SOURCES ${ECMA_SRC_DIR}/generator_helper.cpp ${ECMA_SRC_DIR}/global_env.cpp ${ECMA_SRC_DIR}/global_env_constants.cpp - ${ECMA_SRC_DIR}/hprof/heap_profiler.cpp - ${ECMA_SRC_DIR}/hprof/heap_profiler_interface.cpp - ${ECMA_SRC_DIR}/hprof/heap_root_visitor.cpp - ${ECMA_SRC_DIR}/hprof/heap_snapshot.cpp - ${ECMA_SRC_DIR}/hprof/heap_snapshot_json_serializer.cpp - ${ECMA_SRC_DIR}/hprof/heap_tracker.cpp - ${ECMA_SRC_DIR}/hprof/string_hashmap.cpp ${ECMA_SRC_DIR}/ic/profile_type_info.cpp ${ECMA_SRC_DIR}/ic/ic_runtime.cpp ${ECMA_SRC_DIR}/ic/ic_runtime_stub.cpp @@ -158,42 +151,18 @@ set(ECMASCRIPT_SOURCES ${ECMA_SRC_DIR}/literal_data_extractor.cpp ${ECMA_SRC_DIR}/message_string.cpp ${ECMA_SRC_DIR}/mem/ecma_reference_processor.cpp - ${ECMA_SRC_DIR}/mem/c_string.cpp - ${ECMA_SRC_DIR}/mem/chunk.cpp - ${ECMA_SRC_DIR}/mem/compress_collector.cpp - ${ECMA_SRC_DIR}/mem/concurrent_marker.cpp - ${ECMA_SRC_DIR}/mem/concurrent_sweeper.cpp + ${ECMA_SRC_DIR}/mem/ecma_string.cpp ${ECMA_SRC_DIR}/mem/mem_manager.cpp - ${ECMA_SRC_DIR}/mem/evacuation_allocator.cpp - ${ECMA_SRC_DIR}/mem/free_object_kind.cpp - ${ECMA_SRC_DIR}/mem/free_object_list.cpp - ${ECMA_SRC_DIR}/mem/gc_stats.cpp - ${ECMA_SRC_DIR}/mem/heap.cpp - ${ECMA_SRC_DIR}/mem/mem_controller.cpp - ${ECMA_SRC_DIR}/mem/mix_space_collector.cpp - ${ECMA_SRC_DIR}/mem/parallel_work_helper.cpp - ${ECMA_SRC_DIR}/mem/parallel_evacuation.cpp - ${ECMA_SRC_DIR}/mem/parallel_marker.cpp - ${ECMA_SRC_DIR}/mem/region_factory.cpp - ${ECMA_SRC_DIR}/mem/semi_space_collector.cpp - ${ECMA_SRC_DIR}/mem/space.cpp - ${ECMA_SRC_DIR}/mem/verification.cpp ${ECMA_SRC_DIR}/napi/jsnapi.cpp ${ECMA_SRC_DIR}/napi/jsnapi_debugger_agent.cpp ${ECMA_SRC_DIR}/object_factory.cpp ${ECMA_SRC_DIR}/object_operator.cpp - ${ECMA_SRC_DIR}/platform/platform.cpp - ${ECMA_SRC_DIR}/platform/runner.cpp - ${ECMA_SRC_DIR}/platform/task_queue.cpp ${ECMA_SRC_DIR}/layout_info.cpp ${ECMA_SRC_DIR}/regexp/dyn_chunk.cpp ${ECMA_SRC_DIR}/regexp/regexp_executor.cpp ${ECMA_SRC_DIR}/regexp/regexp_opcode.cpp ${ECMA_SRC_DIR}/regexp/regexp_parser.cpp ${ECMA_SRC_DIR}/regexp/regexp_parser_cache.cpp - ${ECMA_SRC_DIR}/snapshot/mem/slot_bit.cpp - ${ECMA_SRC_DIR}/snapshot/mem/snapshot.cpp - ${ECMA_SRC_DIR}/snapshot/mem/snapshot_serialize.cpp ${ECMA_SRC_DIR}/tagged_dictionary.cpp ${ECMA_SRC_DIR}/template_string.cpp ${ECMA_SRC_DIR}/vmstat/caller_stat.cpp @@ -246,8 +215,6 @@ endif() add_dependencies(arkruntime_interpreter_impl arkcompiler) -add_subdirectory(snapshot/mem) - # Runtime uses unicode and i18n. set(ICU_INCLUDE_DIR ${PANDA_THIRD_PARTY_SOURCES_DIR}/icu/icu4c/source/common @@ -297,11 +264,6 @@ set_source_files_properties(${ECMA_SRC_DIR}/js_number_format.cpp PROPERTIES COMP set_source_files_properties(${ECMA_SRC_DIR}/global_env.cpp PROPERTIES COMPILE_FLAGS -Wno-shadow) set_source_files_properties(${ECMA_SRC_DIR}/ecma_vm.cpp PROPERTIES COMPILE_FLAGS -Wno-shadow) -set_source_files_properties(${ECMA_SRC_DIR}/mem/verification.cpp PROPERTIES COMPILE_FLAGS -Wno-shadow) -set_source_files_properties(${ECMA_SRC_DIR}/mem/semi_space_collector.cpp PROPERTIES COMPILE_FLAGS -Wno-shadow) - -set_source_files_properties(${ECMA_SRC_DIR}/snapshot/mem/snapshot_serialize.cpp PROPERTIES COMPILE_FLAGS -Wno-shadow) - set_source_files_properties(${ECMA_SRC_DIR}/builtins.cpp PROPERTIES COMPILE_FLAGS -Wno-shadow) set_source_files_properties(${ECMA_SRC_DIR}/builtins/builtins_string.cpp PROPERTIES COMPILE_FLAGS -Wno-shadow) set_source_files_properties(${ECMA_SRC_DIR}/builtins/builtins_locale.cpp PROPERTIES COMPILE_FLAGS -Wno-shadow) diff --git a/runtime/base/error_helper.cpp b/runtime/base/error_helper.cpp index e87756cbdc2781ea32d9be9b7685f8e9b1a6bdfa..f6453e33d7ce61c305d3f4cc2688a931e470b0b2 100644 --- a/runtime/base/error_helper.cpp +++ b/runtime/base/error_helper.cpp @@ -163,7 +163,7 @@ JSTaggedValue ErrorHelper::ErrorCommonConstructor(EcmaRuntimeCallInfo *argv, return nativeInstanceObj.GetTaggedValue(); } -CString ErrorHelper::DecodeFunctionName(const CString &name) +PandaString ErrorHelper::DecodeFunctionName(const PandaString &name) { if (name.empty()) { return "anonymous"; @@ -173,16 +173,16 @@ CString ErrorHelper::DecodeFunctionName(const CString &name) JSHandle ErrorHelper::BuildEcmaStackTrace(JSThread *thread) { - CString data = BuildNativeEcmaStackTrace(thread); + PandaString data = BuildNativeEcmaStackTrace(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); LOG(DEBUG, ECMASCRIPT) << data; return factory->NewFromString(data); } -CString ErrorHelper::BuildNativeEcmaStackTrace(JSThread *thread) +PandaString ErrorHelper::BuildNativeEcmaStackTrace(JSThread *thread) { auto ecmaVm = thread->GetEcmaVM(); - CString data; + PandaString data; for (auto stack = StackWalker::Create(thread); stack.HasFrame(); stack.NextFrame()) { auto method = stack.GetMethod(); @@ -194,7 +194,7 @@ CString ErrorHelper::BuildNativeEcmaStackTrace(JSThread *thread) data.append(" ("); // source file PtJSExtractor *debugExtractor = ecmaVm->GetDebugInfoExtractor(method->GetPandaFile()); - const CString &sourceFile = debugExtractor->GetSourceFile(method->GetFileId()); + const PandaString &sourceFile = debugExtractor->GetSourceFile(method->GetFileId()); if (sourceFile.empty()) { data.push_back('?'); } else { @@ -203,9 +203,9 @@ CString ErrorHelper::BuildNativeEcmaStackTrace(JSThread *thread) data.push_back(':'); // line number and column number auto callbackFunc = [&data](size_t line, size_t column) -> bool { - data += ToCString(line + 1); + data += ToPandaString(line + 1); data.push_back(':'); - data += ToCString(column + 1); + data += ToPandaString(column + 1); return true; }; if (!debugExtractor->MatchWithOffset(callbackFunc, method->GetFileId(), stack.GetBytecodePc())) { diff --git a/runtime/base/error_helper.h b/runtime/base/error_helper.h index 46b1c071dcb4bca39218d1dbc28554b79d947f15..c6e9420c9839c4af436d834ac2abc314b072656b 100644 --- a/runtime/base/error_helper.h +++ b/runtime/base/error_helper.h @@ -19,7 +19,7 @@ #include "plugins/ecmascript/runtime/base/error_type.h" #include "plugins/ecmascript/runtime/ecma_runtime_call_info.h" #include "plugins/ecmascript/runtime/js_handle.h" -#include "plugins/ecmascript/runtime/mem/c_string.h" +#include "plugins/ecmascript/runtime/mem/ecma_string.h" namespace panda::ecmascript::base { constexpr char DEFAULT_EMPTY_STACK_TRACE[] = "stack is empty"; // NOLINT (modernize-avoid-c-arrays) @@ -31,10 +31,10 @@ public: static JSTaggedValue ErrorCommonConstructor(EcmaRuntimeCallInfo *argv, const ErrorType &errorType); - static CString BuildNativeEcmaStackTrace(JSThread *thread); + static PandaString BuildNativeEcmaStackTrace(JSThread *thread); private: - static CString DecodeFunctionName(const CString &name); + static PandaString DecodeFunctionName(const PandaString &name); static JSHandle BuildEcmaStackTrace(JSThread *thread); static JSHandle GetErrorName(JSThread *thread, const JSHandle &name, diff --git a/runtime/base/gc_ring_buffer.h b/runtime/base/gc_ring_buffer.h deleted file mode 100644 index dca89bed27cde0bdaa13e08222d4b0a5c24a7b41..0000000000000000000000000000000000000000 --- a/runtime/base/gc_ring_buffer.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_BASE_GC_RING_BUFFER_H -#define ECMASCRIPT_BASE_GC_RING_BUFFER_H - -#include - -#include "libpandabase/macros.h" - -namespace panda::ecmascript::base { -// GC Ring Buffer is base tool class. It will be used to collect the data of the last N GCs. The max length is -// fixed, so we call it a GC ring buffer. In this class, we define the functions to push data, count the length, -// return the sum and reset data. -template -class GCRingBuffer { -public: - GCRingBuffer() = default; - ~GCRingBuffer() = default; - NO_COPY_SEMANTIC(GCRingBuffer); - NO_MOVE_SEMANTIC(GCRingBuffer); - - void Push(const T &value) - { - if (count_ == N) { - elements_[start_++] = value; - if (start_ == N) { - start_ = 0; - } - } else { - ASSERT(start_ == 0); - elements_[count_++] = value; - } - } - - int Count() const - { - return count_; - } - - // This function will return the sum of the elements_. The parameter callback - // should define the sum function of data type T. - template - T Sum(Callback callback, const T &initial) const - { - T result = initial; - for (int i = 0; i < count_; i++) { - result = callback(result, elements_[i]); - } - return result; - } - - void Reset() - { - start_ = count_ = 0; - } - -private: - std::array elements_; - int start_ {0}; - int count_ {0}; -}; -} // namespace panda::ecmascript::base - -#endif // ECMASCRIPT_BASE_GC_RING_BUFFER_H \ No newline at end of file diff --git a/runtime/base/json_parser.h b/runtime/base/json_parser.h index 82f650eb1dcdd5f6ed9b714d00238960cbaf8411..edbe03dbb8936fd1408ab5a9fca5715954ba9ccf 100644 --- a/runtime/base/json_parser.h +++ b/runtime/base/json_parser.h @@ -79,7 +79,7 @@ public: ASSERT(str != nullptr); isAsciiString_ = true; uint32_t len = str->GetUtf8Length(); - CVector buf(len); + PandaVector buf(len); str->CopyDataUtf8(buf.data(), len); Text begin = buf.data(); return Parse(begin, begin + str->GetLength()); @@ -89,7 +89,7 @@ public: { ASSERT(str != nullptr); uint32_t len = str->GetLength(); - CVector buf(len); + PandaVector buf(len); str->CopyDataUtf16(buf.data(), len); Text begin = buf.data(); return Parse(begin, begin + len); @@ -179,7 +179,7 @@ private: return IsFastParseAsciiString(isFastString); } - bool ParseBackslash(CString &res) + bool ParseBackslash(PandaString &res) { if (current_ == end_) { return false; @@ -211,7 +211,7 @@ private: res += "\t"; break; case 'u': { - CVector vec; + PandaVector vec; if (UNLIKELY(!ConvertStringUnicode(vec))) { return false; } @@ -229,7 +229,7 @@ private: JSTaggedValue SlowParseString() { end_--; - CString res; + PandaString res; while (current_ <= end_) { if (*current_ == '\\') { bool isLegalChar = ParseBackslash(res); @@ -258,7 +258,7 @@ private: } if (isFastString) { if (isAscii) { - CString value(current_, end_); + PandaString value(current_, end_); current_ = end_; return factory_ ->NewFromUtf8LiteralUnCheck(reinterpret_cast(value.c_str()), value.length(), @@ -282,7 +282,7 @@ private: } if (LIKELY(isFastString)) { if (isAscii) { - CString value(current_, end_); + PandaString value(current_, end_); return factory_ ->NewFromUtf8LiteralUnCheck(reinterpret_cast(value.c_str()), value.length(), true) @@ -438,7 +438,7 @@ private: } } - JSTaggedValue ParseLiteral(const CString &str, Tokens literalToken) + JSTaggedValue ParseLiteral(const PandaString &str, Tokens literalToken) { uint32_t strLen = str.size() - 1; uint32_t remainingLength = range_ - current_; @@ -462,7 +462,7 @@ private: THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Text in JSON", JSTaggedValue::Exception()); } - bool MatchText(const CString &str, uint32_t matchLen) + bool MatchText(const PandaString &str, uint32_t matchLen) { const char *text = str.c_str(); uint32_t pos = 1; @@ -669,7 +669,7 @@ private: return true; } - bool ConvertStringUnicode(CVector &vec) + bool ConvertStringUnicode(PandaVector &vec) { uint32_t remainingLength = end_ - current_; if (remainingLength < UNICODE_DIGIT_LENGTH) { diff --git a/runtime/base/json_stringifier.cpp b/runtime/base/json_stringifier.cpp index b860b2f1cc3537970970a526ae90a114f6487197..b883a433c6fed45f8a768056170e9f36bc407bc3 100644 --- a/runtime/base/json_stringifier.cpp +++ b/runtime/base/json_stringifier.cpp @@ -54,9 +54,9 @@ bool JsonStringifier::IsFastValueToQuotedString(const char *value) return true; } -CString JsonStringifier::ValueToQuotedString(const CString &str) +PandaString JsonStringifier::ValueToQuotedString(const PandaString &str) { - CString product; + PandaString product; const char *value = str.c_str(); // fast mode bool isFast = IsFastValueToQuotedString(value); @@ -276,11 +276,11 @@ bool JsonStringifier::CalculateNumberGap(JSTaggedValue gap) bool JsonStringifier::CalculateStringGap(const JSHandle &primString) { - CString gapString = ConvertToString(*primString); + PandaString gapString = ConvertToPandaString(*primString); int gapLen = gapString.length(); if (gapLen > 0) { int gapLength = std::min(gapLen, GAP_MAX_LEN); - CString str = gapString.substr(0, gapLength); + PandaString str = gapString.substr(0, gapLength); gap_ += str; gap_.append("\0"); } @@ -349,7 +349,7 @@ JSTaggedValue JsonStringifier::SerializeJSONProperty(const JSHandle(valHandle)); + PandaString str = ConvertToPandaString(*JSHandle(valHandle)); str = ValueToQuotedString(str); result_ += str; return valHandle.GetTaggedValue(); @@ -398,8 +398,8 @@ JSTaggedValue JsonStringifier::SerializeJSONProperty(const JSHandle &key, bool hasContent) { - CString stepBegin; - CString stepEnd; + PandaString stepBegin; + PandaString stepEnd; if (hasContent) { result_ += ","; } @@ -408,13 +408,13 @@ void JsonStringifier::SerializeObjectKey(const JSHandle &key, boo stepBegin += indent_; stepEnd += " "; } - CString str; + PandaString str; if (key->IsString()) { - str = ConvertToString(EcmaString::Cast(key->GetTaggedObject())); + str = ConvertToPandaString(EcmaString::Cast(key->GetTaggedObject())); } else if (key->IsInt()) { str = NumberHelper::IntToString(static_cast(key->GetInt())); } else { - str = ConvertToString(*JSTaggedValue::ToString(thread_, key)); + str = ConvertToPandaString(*JSTaggedValue::ToString(thread_, key)); } result_ += stepBegin; str = ValueToQuotedString(str); @@ -450,7 +450,7 @@ bool JsonStringifier::SerializeJSONObject(const JSHandle &value, THROW_TYPE_ERROR_AND_RETURN(thread_, "stack contains value", true); } - CString stepback = indent_; + PandaString stepback = indent_; indent_ += gap_; result_ += "{"; @@ -506,8 +506,8 @@ bool JsonStringifier::SerializeJSProxy(const JSHandle &object, co THROW_TYPE_ERROR_AND_RETURN(thread_, "stack contains value", true); } - CString stepback = indent_; - CString stepBegin; + PandaString stepback = indent_; + PandaString stepBegin; indent_ += gap_; if (!gap_.empty()) { @@ -558,8 +558,8 @@ bool JsonStringifier::SerializeJSArray(const JSHandle &value, con THROW_TYPE_ERROR_AND_RETURN(thread_, "stack contains value", true); } - CString stepback = indent_; - CString stepBegin; + PandaString stepback = indent_; + PandaString stepBegin; indent_ += gap_; if (!gap_.empty()) { @@ -610,14 +610,14 @@ void JsonStringifier::SerilaizePrimitiveRef(const JSHandle &primi if (primitive.IsString()) { auto priStr = JSTaggedValue::ToString(thread_, primitiveRef); RETURN_IF_ABRUPT_COMPLETION(thread_); - CString str = ConvertToString(*priStr); + PandaString str = ConvertToPandaString(*priStr); str = ValueToQuotedString(str); result_ += str; } else if (primitive.IsNumber()) { auto priNum = JSTaggedValue::ToNumber(thread_, primitiveRef); RETURN_IF_ABRUPT_COMPLETION(thread_); if (std::isfinite(priNum.GetNumber())) { - result_ += ConvertToString(*base::NumberHelper::NumberToString(thread_, priNum)); + result_ += ConvertToPandaString(*base::NumberHelper::NumberToString(thread_, priNum)); } else { result_ += "null"; } @@ -642,7 +642,7 @@ bool JsonStringifier::SerializeElements(const JSHandle &obj, const JSH } } else { JSHandle numberDic(elementsArr); - CVector> sortArr; + PandaVector> sortArr; int size = numberDic->Size(); for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key = numberDic->GetKey(hashIndex); diff --git a/runtime/base/json_stringifier.h b/runtime/base/json_stringifier.h index bdc0b784f4845e5f3456f6483db5f7cb2e87ab49..fed09e9102f56ef92a9937f74c87d177e0d92036 100644 --- a/runtime/base/json_stringifier.h +++ b/runtime/base/json_stringifier.h @@ -20,7 +20,6 @@ #include "plugins/ecmascript/runtime/js_handle.h" #include "plugins/ecmascript/runtime/object_factory.h" #include "plugins/ecmascript/runtime/global_env.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" namespace panda::ecmascript::base { class JsonStringifier { @@ -40,7 +39,7 @@ public: const JSHandle &gap); private: - CString ValueToQuotedString(const CString &str); + PandaString ValueToQuotedString(const PandaString &str); bool IsFastValueToQuotedString(const char *value); @@ -80,13 +79,13 @@ private: return a->GetNumber() < b->GetNumber(); } - CString gap_; - CString result_; - CString indent_; + PandaString gap_; + PandaString result_; + PandaString indent_; JSThread *thread_ {nullptr}; ObjectFactory *factory_ {nullptr}; - CVector> stack_; - CVector> propList_; + PandaVector> stack_; + PandaVector> propList_; JSMutableHandle handleKey_; JSMutableHandle handleValue_; }; diff --git a/runtime/base/number_helper.cpp b/runtime/base/number_helper.cpp index 581d378cb30af6bc4bcb26beebb85e3e245e727c..009b775eb4f6430364f824143070a61f320a3a51 100644 --- a/runtime/base/number_helper.cpp +++ b/runtime/base/number_helper.cpp @@ -114,7 +114,7 @@ JSTaggedValue NumberHelper::DoubleToString(JSThread *thread, double number, int value += 1; double delta = HALF * (bit_cast(value) - number); - CString result; + PandaString result; if (numberFraction != 0 && numberFraction >= delta) { result += "."; result += DecimalsToString(&numberInteger, numberFraction, radix, delta); @@ -131,15 +131,15 @@ JSTaggedValue NumberHelper::DoubleToString(JSThread *thread, double number, int JSTaggedValue NumberHelper::DoubleToExponential(JSThread *thread, double number, int digit) { - CStringStream ss; + PandaStringStream ss; if (digit < 0) { ss << std::setiosflags(std::ios::scientific) << std::setprecision(base::MAX_PRECISION) << number; } else { ss << std::setiosflags(std::ios::scientific) << std::setprecision(digit) << number; } - CString result = ss.str(); + PandaString result = ss.str(); size_t found = result.find_last_of('e'); - if (found != CString::npos && found < result.size() - 2 && result[found + 2] == '0') { + if (found != PandaString::npos && found < result.size() - 2 && result[found + 2] == '0') { result.erase(found + 2, 1); // 2:offset of e } if (digit < 0) { @@ -161,7 +161,7 @@ JSTaggedValue NumberHelper::DoubleToExponential(JSThread *thread, double number, JSTaggedValue NumberHelper::DoubleToFixed(JSThread *thread, double number, int digit) { - CStringStream ss; + PandaStringStream ss; ss << std::setiosflags(std::ios::fixed) << std::setprecision(digit) << number; return BuiltinsBase::GetTaggedString(thread, ss.str().c_str()); } @@ -171,7 +171,7 @@ JSTaggedValue NumberHelper::DoubleToPrecision(JSThread *thread, double number, i if (number == 0.0) { return DoubleToFixed(thread, number, digit - 1); } - CStringStream ss; + PandaStringStream ss; double positiveNumber = number > 0 ? number : -number; int logDigit = std::floor(log10(positiveNumber)); int radixDigit = digit - logDigit - 1; @@ -270,13 +270,13 @@ char NumberHelper::Carry(char current, int radix) return CHARS[digit]; } -CString NumberHelper::IntegerToString(double number, int radix) +PandaString NumberHelper::IntegerToString(double number, int radix) { ASSERT(radix >= MIN_RADIX && radix <= MAX_RADIX); - CString result; + PandaString result; while (number / radix > MAX_MANTISSA) { number /= radix; - result = CString("0").append(result); + result = PandaString("0").append(result); } do { double remainder = std::fmod(number, radix); @@ -286,9 +286,9 @@ CString NumberHelper::IntegerToString(double number, int radix) return result; } -CString NumberHelper::DecimalsToString(double *numberInteger, double fraction, int radix, double delta) +PandaString NumberHelper::DecimalsToString(double *numberInteger, double fraction, int radix, double delta) { - CString result; + PandaString result; while (fraction >= delta) { fraction *= radix; delta *= radix; @@ -313,16 +313,16 @@ CString NumberHelper::DecimalsToString(double *numberInteger, double fraction, i } // delete 0 in the end size_t found = result.find_last_not_of('0'); - if (found != CString::npos) { + if (found != PandaString::npos) { result.erase(found + 1); } return result; } -CString NumberHelper::IntToString(int number) +PandaString NumberHelper::IntToString(int number) { - return ToCString(number); + return ToPandaString(number); } JSTaggedValue NumberHelper::Pow(double base, double exponent) @@ -374,7 +374,7 @@ JSHandle NumberHelper::NumberToString(const JSThread *thread, JSTagg // and k is as small as possible. If there are multiple possibilities for s, choose the value of s for which s × // 10n−k is closest in value to m. If there are two such possible values of s, choose the one that is even. Note // that k is the number of digits in the decimal representation of s and that s is not divisible by 10. - CStringStream str; + PandaStringStream str; str << std::scientific << std::showpoint << std::setprecision(DOUBLE_MAX_PRECISION) << d; if (strtod(str.str().c_str(), nullptr) != d) { str.clear(); @@ -609,7 +609,7 @@ double NumberHelper::StringToDouble(const uint8_t *start, const uint8_t *end, ui } // 10. build StringNumericLiteral string - CString buffer; + PandaString buffer; if (sign == Sign::NEG) { buffer += "-"; } diff --git a/runtime/base/number_helper.h b/runtime/base/number_helper.h index f64fd569232407a53614bb693af3f21111d7338a..2bc505c3e1b4d6aa6acd8d37b3de20b4a81db1f6 100644 --- a/runtime/base/number_helper.h +++ b/runtime/base/number_helper.h @@ -90,13 +90,13 @@ public: static JSTaggedValue DoubleToFixed(JSThread *thread, double number, int digit); static JSTaggedValue DoubleToPrecision(JSThread *thread, double number, int digit); static JSTaggedValue StringToDoubleWithRadix(const uint8_t *start, const uint8_t *end, int radix); - static CString IntToString(int number); + static PandaString IntToString(int number); private: static char Carry(char current, int radix); static double Strtod(const char *str, int exponent, uint8_t radix); - static CString IntegerToString(double number, int radix); - static CString DecimalsToString(double *numberInteger, double fraction, int radix, double delta); + static PandaString IntegerToString(double number, int radix); + static PandaString DecimalsToString(double *numberInteger, double fraction, int radix, double delta); static bool IsNonspace(uint16_t c); static bool GotoNonspace(uint8_t **ptr, const uint8_t *end); }; diff --git a/runtime/base/string_helper.cpp b/runtime/base/string_helper.cpp index ef014d704b95344657ecf1b382398158e3394a02..9a009b18583fc59f1d94663a4163e60e99f8d448 100644 --- a/runtime/base/string_helper.cpp +++ b/runtime/base/string_helper.cpp @@ -19,7 +19,7 @@ namespace panda::ecmascript::base { std::string StringHelper::ToStdString(EcmaString *string) { - return std::string(ConvertToString(string)); + return std::string(ConvertToPandaString(string)); } bool StringHelper::CheckDuplicate(EcmaString *string) diff --git a/runtime/base/string_helper.h b/runtime/base/string_helper.h index ae8937aed7f96d0bb9c1479fca4cf603c386b9b2..1b2d06385363207acf14b6cb3779c11a5e821a1d 100644 --- a/runtime/base/string_helper.h +++ b/runtime/base/string_helper.h @@ -27,7 +27,6 @@ #include "plugins/ecmascript/runtime/ecma_string-inl.h" #include "plugins/ecmascript/runtime/ecma_vm.h" #include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/assert_scope-inl.h" #include "plugins/ecmascript/runtime/object_factory.h" #include "ark-third-party/icu/icu4c/source/common/unicode/unistr.h" #include "libpandafile/file_items.h" @@ -45,20 +44,19 @@ public: static inline bool Contains(const EcmaString *string, const EcmaString *other) { - [[maybe_unused]] DisallowGarbageCollection noGc; - CString str = ConvertToString(string, StringConvertedUsage::LOGICOPERATION); - CString oth = ConvertToString(other, StringConvertedUsage::LOGICOPERATION); - CString::size_type index = str.find(oth); - return (index != CString::npos); + PandaString str = ConvertToPandaString(string, StringConvertedUsage::LOGICOPERATION); + PandaString oth = ConvertToPandaString(other, StringConvertedUsage::LOGICOPERATION); + PandaString::size_type index = str.find(oth); + return (index != PandaString::npos); } - static inline CString RepalceAll(CString str, const CString &oldValue, const CString &newValue) + static inline PandaString RepalceAll(PandaString str, const PandaString &oldValue, const PandaString &newValue) { if (oldValue.empty() || oldValue == newValue) { return str; } - CString::size_type pos(0); - while ((pos = str.find(oldValue, pos)) != CString::npos) { + PandaString::size_type pos(0); + while ((pos = str.find(oldValue, pos)) != PandaString::npos) { str.replace(pos, oldValue.length(), newValue); pos += newValue.length(); } @@ -68,7 +66,7 @@ public: static inline std::string SubString(const JSHandle &string, uint32_t start, uint32_t length) { return std::string( - ConvertToString(string.GetObject(), start, length, StringConvertedUsage::LOGICOPERATION)); + ConvertToPandaString(string.GetObject(), start, length, StringConvertedUsage::LOGICOPERATION)); } static inline std::u16string Utf16ToU16String(const uint16_t *utf16Data, uint32_t dataLen) diff --git a/runtime/base/typed_array_helper.cpp b/runtime/base/typed_array_helper.cpp index 979ec7601faf0c818a48427ecd82faf77cf19db4..9c1475003b4d1add8598a56e587efbdd361122d3 100644 --- a/runtime/base/typed_array_helper.cpp +++ b/runtime/base/typed_array_helper.cpp @@ -96,7 +96,7 @@ JSTaggedValue TypedArrayHelper::CreateFromOrdinaryObject(EcmaRuntimeCallInfo *ar // 6. If usingIterator is not undefined, then if (!usingIterator->IsUndefined()) { - CVector> vec; + PandaVector> vec; // a. Let values be ? IterableToList(object, usingIterator). // b. Let len be the number of elements in values. // c. Perform ? AllocateTypedArrayBuffer(O, len). diff --git a/runtime/builtins/builtins_array.cpp b/runtime/builtins/builtins_array.cpp index 90b0698192d4be5cd819e50a402f20857a1a4882..cbd3dc352840aecb5a9780dbc8a1ffd1b22e954e 100644 --- a/runtime/builtins/builtins_array.cpp +++ b/runtime/builtins/builtins_array.cpp @@ -2626,7 +2626,7 @@ JSTaggedValue BuiltinsArray::ToLocaleString(EcmaRuntimeCallInfo *argv) } JSHandle sepStringHandle = JSTaggedValue::ToString(thread, sepHandle); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - CString sepString = ConvertToString(*sepStringHandle); + PandaString sepString = ConvertToPandaString(*sepStringHandle); // 6. If len is zero, return the empty String. if (len == 0) { return GetTaggedString(thread, ""); @@ -2636,7 +2636,7 @@ JSTaggedValue BuiltinsArray::ToLocaleString(EcmaRuntimeCallInfo *argv) JSHandle locales = GetCallArg(argv, 0); JSHandle options = GetCallArg(argv, 1); - CString concatStr; + PandaString concatStr; // 7. Let firstElement be Get(array, "0"). // 8. ReturnIfAbrupt(firstElement). // 9. If firstElement is undefined or null, then @@ -2674,7 +2674,7 @@ JSTaggedValue BuiltinsArray::ToLocaleString(EcmaRuntimeCallInfo *argv) JSHandle nextHandle(thread, next); JSHandle nextStringHandle = JSTaggedValue::ToString(thread, nextHandle); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - CString nextString = ConvertToString(*nextStringHandle); + PandaString nextString = ConvertToPandaString(*nextStringHandle); if (k > 0) { concatStr += sepString; concatStr += nextString; diff --git a/runtime/builtins/builtins_date.cpp b/runtime/builtins/builtins_date.cpp index 59c17f7128dd5a3d6ff4ce03a25c49ec563e5935..391bb5a997a45b897372a6526daf2722f0f3fe7b 100644 --- a/runtime/builtins/builtins_date.cpp +++ b/runtime/builtins/builtins_date.cpp @@ -35,7 +35,7 @@ JSTaggedValue BuiltinsDate::DateConstructor(EcmaRuntimeCallInfo *argv) JSHandle newTarget = GetNewTarget(argv); if (newTarget->IsUndefined()) { double now = JSDate::Now().GetDouble(); - CString str = JSDate::ToDateString(now); + PandaString str = JSDate::ToDateString(now); return GetTaggedString(thread, str.c_str()); } diff --git a/runtime/builtins/builtins_global.cpp b/runtime/builtins/builtins_global.cpp index 7275383cc6e7f4f196c2c96a14788aa62a60e29c..399853f7a897ddd5b602b721b89452297702b757 100644 --- a/runtime/builtins/builtins_global.cpp +++ b/runtime/builtins/builtins_global.cpp @@ -24,7 +24,6 @@ #include "plugins/ecmascript/runtime/internal_call_params.h" #include "plugins/ecmascript/runtime/interpreter/slow_runtime_helper.h" #include "plugins/ecmascript/runtime/js_invoker.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "plugins/ecmascript/runtime/tagged_array-inl.h" namespace panda::ecmascript::builtins { @@ -474,7 +473,7 @@ void BuiltinsGlobal::PrintString([[maybe_unused]] JSThread *thread, EcmaString * return; } - CString buffer = ConvertToString(string); + PandaString buffer = ConvertToPandaString(string); std::cout << buffer; } diff --git a/runtime/builtins/builtins_locale.cpp b/runtime/builtins/builtins_locale.cpp index e0f2c50994c299a8bec1013f5080034a9553c03f..a86d4ae819343b16a19d3db2999c91f3517c48c7 100644 --- a/runtime/builtins/builtins_locale.cpp +++ b/runtime/builtins/builtins_locale.cpp @@ -128,7 +128,7 @@ JSTaggedValue BuiltinsLocale::Minimize(EcmaRuntimeCallInfo *argv) ASSERT(U_SUCCESS(status)); ASSERT(!source.isBogus()); - [[maybe_unused]] auto res = source.toLanguageTag(status); + [[maybe_unused]] auto res = source.toLanguageTag(status); // 4. Return ! Construct(%Locale%, minimal). EcmaVM *ecmaVm = thread->GetEcmaVM(); @@ -254,7 +254,7 @@ JSTaggedValue BuiltinsLocale::GetNumeric(EcmaRuntimeCallInfo *argv) JSHandle locale = JSHandle::Cast(loc); icu::Locale *icuLocale = locale->GetIcuLocale(); UErrorCode status = U_ZERO_ERROR; - auto numeric = icuLocale->getUnicodeKeywordValue("kn", status); + auto numeric = icuLocale->getUnicodeKeywordValue("kn", status); JSTaggedValue result = (numeric == "true") ? JSTaggedValue::True() : JSTaggedValue::False(); return result; } @@ -292,7 +292,7 @@ JSTaggedValue BuiltinsLocale::GetLanguage(EcmaRuntimeCallInfo *argv) // 5. Return the substring of locale corresponding to the unicode_language_subtag production of the // unicode_language_id. JSHandle result = factory->NewFromString("undefined"); - CString language = locale->GetIcuLocale()->getLanguage(); + PandaString language = locale->GetIcuLocale()->getLanguage(); if (language.empty()) { return result.GetTaggedValue(); } @@ -320,7 +320,7 @@ JSTaggedValue BuiltinsLocale::GetScript(EcmaRuntimeCallInfo *argv) // 6. Return the substring of locale corresponding to the unicode_script_subtag production of the // unicode_language_id. JSHandle result(thread, JSTaggedValue::Undefined()); - CString script = locale->GetIcuLocale()->getScript(); + PandaString script = locale->GetIcuLocale()->getScript(); if (script.empty()) { return result.GetTaggedValue(); } @@ -348,7 +348,7 @@ JSTaggedValue BuiltinsLocale::GetRegion(EcmaRuntimeCallInfo *argv) // return undefined. // 6. Return the substring of locale corresponding to the unicode_region_subtag production of the // unicode_language_id. - CString region = locale->GetIcuLocale()->getCountry(); + PandaString region = locale->GetIcuLocale()->getCountry(); if (region.empty()) { return globalConst->GetUndefined(); } diff --git a/runtime/builtins/builtins_number.cpp b/runtime/builtins/builtins_number.cpp index 8fbef396abe719d8ef2094b5bc8b6e49788394b7..2c9c0a66f94a5a7dd2a8ab6798db4efaffa6e16a 100644 --- a/runtime/builtins/builtins_number.cpp +++ b/runtime/builtins/builtins_number.cpp @@ -24,7 +24,6 @@ #include "plugins/ecmascript/runtime/js_primitive_ref.h" #include "plugins/ecmascript/runtime/js_tagged_number.h" #include "plugins/ecmascript/runtime/js_tagged_value-inl.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "plugins/ecmascript/runtime/object_factory.h" #include "plugins/ecmascript/runtime/tagged_hash_table.h" @@ -166,7 +165,7 @@ JSTaggedValue BuiltinsNumber::ParseFloat(EcmaRuntimeCallInfo *argv) if (UNLIKELY(numberString->IsUtf16())) { size_t len = ecmascript::base::utf_helper::Utf16ToUtf8Size(numberString->GetDataUtf16(), numberString->GetLength()) - 1; - CVector buf(len); + PandaVector buf(len); len = ecmascript::base::utf_helper::ConvertRegionUtf16ToUtf8(numberString->GetDataUtf16(), buf.data(), numberString->GetLength(), len, 0); auto str = Span(buf.data(), len); @@ -206,7 +205,7 @@ JSTaggedValue BuiltinsNumber::ParseInt(EcmaRuntimeCallInfo *argv) if (UNLIKELY(numberString->IsUtf16())) { size_t len = ecmascript::base::utf_helper::Utf16ToUtf8Size(numberString->GetDataUtf16(), numberString->GetLength()) - 1; - CVector buf(len); + PandaVector buf(len); len = ecmascript::base::utf_helper::ConvertRegionUtf16ToUtf8(numberString->GetDataUtf16(), buf.data(), numberString->GetLength(), len, 0); auto str = Span(buf.data(), len); diff --git a/runtime/builtins/builtins_promise.cpp b/runtime/builtins/builtins_promise.cpp index 1c89cd8f7d14c2e854b254113cf03d94f7845f64..f996908c8d6ffb71085e36f42977a206686fb502 100644 --- a/runtime/builtins/builtins_promise.cpp +++ b/runtime/builtins/builtins_promise.cpp @@ -29,7 +29,6 @@ #include "plugins/ecmascript/runtime/js_tagged_number.h" #include "plugins/ecmascript/runtime/js_tagged_value-inl.h" #include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/assert_scope-inl.h" #include "plugins/ecmascript/runtime/object_factory.h" namespace panda::ecmascript::builtins { diff --git a/runtime/builtins/builtins_promise_handler.cpp b/runtime/builtins/builtins_promise_handler.cpp index bcf66c0c6915017667c46fa8122bada8f7c4bb8d..bfaf0c02af7e7e892a5627aa7ba527e13e5390d6 100644 --- a/runtime/builtins/builtins_promise_handler.cpp +++ b/runtime/builtins/builtins_promise_handler.cpp @@ -23,7 +23,6 @@ #include "plugins/ecmascript/runtime/js_handle.h" #include "plugins/ecmascript/runtime/js_promise.h" #include "plugins/ecmascript/runtime/js_tagged_value-inl.h" -#include "plugins/ecmascript/runtime/mem/assert_scope-inl.h" namespace panda::ecmascript::builtins { // es6 25.4.1.3.2 Promise Resolve Functions diff --git a/runtime/builtins/builtins_regexp.cpp b/runtime/builtins/builtins_regexp.cpp index eedeba4aa9431d5076424c389d97b3a6a41b7d89..3bbf9b9ac55b39a5991fa2e3c7741a31a53cdc21 100644 --- a/runtime/builtins/builtins_regexp.cpp +++ b/runtime/builtins/builtins_regexp.cpp @@ -27,9 +27,6 @@ #include "plugins/ecmascript/runtime/js_object-inl.h" #include "plugins/ecmascript/runtime/js_regexp.h" #include "plugins/ecmascript/runtime/js_tagged_value-inl.h" -#include "plugins/ecmascript/runtime/mem/assert_scope-inl.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" -#include "plugins/ecmascript/runtime/mem/chunk_containers.h" #include "plugins/ecmascript/runtime/object_factory.h" #include "plugins/ecmascript/runtime/regexp/regexp_parser_cache.h" #include "plugins/ecmascript/runtime/tagged_array-inl.h" @@ -58,8 +55,6 @@ JSTaggedValue BuiltinsRegExp::RegExpConstructor(EcmaRuntimeCallInfo *argv) auto ecmaVm = thread->GetEcmaVM(); JSHandle env = ecmaVm->GetGlobalEnv(); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); - // disable gc - [[maybe_unused]] DisallowGarbageCollection no_gc; // 4.a Let newTarget be the active function object. newTarget = env->GetRegExpFunction(); JSHandle constructorString = globalConst->GetHandledConstructorString(); @@ -99,8 +94,6 @@ JSTaggedValue BuiltinsRegExp::RegExpConstructor(EcmaRuntimeCallInfo *argv) } else if (patternIsRegExp) { JSHandle sourceString(factory->NewFromCanBeCompressString("source")); JSHandle flagsString(factory->NewFromCanBeCompressString("flags")); - // disable gc - [[maybe_unused]] DisallowGarbageCollection noGc; // 6.a Let P be Get(pattern, "source"). patternTemp = JSObject::GetProperty(thread, pattern, sourceString).GetValue(); // 6.b ReturnIfAbrupt(P). @@ -246,17 +239,17 @@ JSHandle ConcatFlags(JSThread *thread, const JSHandle temp = factory->GetEmptyString(); - if (CString("global") == name) { + if (PandaString("global") == name) { temp = factory->NewFromString("g"); - } else if (CString("ignoreCase") == name) { + } else if (PandaString("ignoreCase") == name) { temp = factory->NewFromString("i"); - } else if (CString("multiline") == name) { + } else if (PandaString("multiline") == name) { temp = factory->NewFromString("m"); - } else if (CString("dotAll") == name) { + } else if (PandaString("dotAll") == name) { temp = factory->NewFromString("s"); - } else if (CString("unicode") == name) { + } else if (PandaString("unicode") == name) { temp = factory->NewFromString("u"); - } else if (CString("sticky") == name) { + } else if (PandaString("sticky") == name) { temp = factory->NewFromString("y"); } JSHandle thisString(string); @@ -595,14 +588,14 @@ JSTaggedValue BuiltinsRegExp::RegExpReplaceFast(JSThread *thread, JSHandleIsUtf16(); const uint8_t *strBuffer; - CVector u8Buffer; - CVector u16Buffer; + PandaVector u8Buffer; + PandaVector u16Buffer; if (isUtf16) { - u16Buffer = CVector(inputLength); + u16Buffer = PandaVector(inputLength); inputString->CopyDataUtf16(u16Buffer.data(), inputLength); strBuffer = reinterpret_cast(u16Buffer.data()); } else { - u8Buffer = CVector(inputLength + 1); + u8Buffer = PandaVector(inputLength + 1); inputString->CopyDataUtf8(u8Buffer.data(), inputLength + 1); strBuffer = u8Buffer.data(); } @@ -834,7 +827,7 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) ++index; } // m. If functionalReplace is true, then - CString replacement; + PandaString replacement; JSHandle replacerArgs = factory->NewTaggedArray(3 + capturesList->GetLength()); // 3: «matched, pos, and string» if (functionalReplace) { @@ -860,14 +853,14 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) JSHandle replacementString = JSTaggedValue::ToString(thread, replValue); // o. ReturnIfAbrupt(replacement). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - replacement = ConvertToString(*replacementString, StringConvertedUsage::LOGICOPERATION); + replacement = ConvertToPandaString(*replacementString, StringConvertedUsage::LOGICOPERATION); } else { // n. Else, JSHandle replacementHandle( thread, BuiltinsString::GetSubstitution(thread, matchString, srcString, position, capturesList, replaceValueHandle)); - replacement = ConvertToString(EcmaString::Cast(replacementHandle->GetTaggedObject()), - StringConvertedUsage::LOGICOPERATION); + replacement = ConvertToPandaString(EcmaString::Cast(replacementHandle->GetTaggedObject()), + StringConvertedUsage::LOGICOPERATION); } // p. If position ≥ nextSourcePosition, then if (position >= nextSourcePosition) { @@ -1190,8 +1183,7 @@ RegExpExecutor::MatchResult BuiltinsRegExp::Matcher(JSThread *thread, const JSHa void *dynBuf = JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer(); auto bytecodeBuffer = reinterpret_cast(dynBuf); // execute - Chunk chunk(thread->GetRegionFactory()); - RegExpExecutor executor(&chunk); + RegExpExecutor executor; if (lastIndex < 0) { lastIndex = 0; } @@ -1318,14 +1310,14 @@ JSTaggedValue BuiltinsRegExp::RegExpBuiltinExec(JSThread *thread, const JSHandle bool isUtf16 = inputString->IsUtf16(); const uint8_t *strBuffer; size_t stringLength = inputString->GetLength(); - CVector u8Buffer; - CVector u16Buffer; + PandaVector u8Buffer; + PandaVector u16Buffer; if (isUtf16) { - u16Buffer = CVector(stringLength); + u16Buffer = PandaVector(stringLength); inputString->CopyDataUtf16(u16Buffer.data(), stringLength); strBuffer = reinterpret_cast(u16Buffer.data()); } else { - u8Buffer = CVector(stringLength + 1); + u8Buffer = PandaVector(stringLength + 1); inputString->CopyDataUtf8(u8Buffer.data(), stringLength + 1); strBuffer = u8Buffer.data(); } @@ -1446,7 +1438,7 @@ JSTaggedValue BuiltinsRegExp::RegExpAlloc(JSThread *thread, const JSHandle(UpdateExpressionFlags(thread, checkStr)); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } - // String -> CString - CString patternStdStr = ConvertToString(*patternStrHandle, StringConvertedUsage::LOGICOPERATION); + // String -> PandaString + PandaString patternStdStr = ConvertToPandaString(*patternStrHandle, StringConvertedUsage::LOGICOPERATION); // 9. 10. - Chunk chunk(thread->GetRegionFactory()); - RegExpParser parser = RegExpParser(&chunk); + RegExpParser parser = RegExpParser(); RegExpParserCache *regExpParserCache = thread->GetEcmaVM()->GetRegExpParserCache(); auto getCache = regExpParserCache->GetCache(*patternStrHandle, flagsBits); if (getCache.first == JSTaggedValue::Hole()) { @@ -1628,10 +1619,10 @@ JSTaggedValue BuiltinsRegExp::RegExpCreate(JSThread *thread, const JSHandle &src, const JSHandle &flags) { - // String -> CString + // String -> PandaString JSHandle srcStr(thread, static_cast(src->GetTaggedObject())); JSHandle flagsStr(thread, static_cast(flags->GetTaggedObject())); - CString srcStdStr = ConvertToString(*srcStr, StringConvertedUsage::LOGICOPERATION); + PandaString srcStdStr = ConvertToPandaString(*srcStr, StringConvertedUsage::LOGICOPERATION); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // "" -> (?:) if (srcStdStr.empty()) { diff --git a/runtime/builtins/builtins_regexp.h b/runtime/builtins/builtins_regexp.h index b5980cf07b0040288ef6664da152b34e30c67ced..776b69ac1812219275260f9f1939f2e7bb0c33a5 100644 --- a/runtime/builtins/builtins_regexp.h +++ b/runtime/builtins/builtins_regexp.h @@ -86,7 +86,7 @@ private: // 21.2.3.2.1 Runtime Semantics: RegExpAlloc ( newTarget ) static JSTaggedValue RegExpAlloc(JSThread *thread, const JSHandle &newTarget); - static uint32_t UpdateExpressionFlags(JSThread *thread, const CString &checkStr); + static uint32_t UpdateExpressionFlags(JSThread *thread, const PandaString &checkStr); // 21.2.3.2.2 Runtime Semantics: RegExpInitialize ( obj, pattern, flags ) static JSTaggedValue RegExpInitialize(JSThread *thread, const JSHandle &obj, diff --git a/runtime/builtins/builtins_string.cpp b/runtime/builtins/builtins_string.cpp index 639841097e49a77e7f8347761e6f800fdd5bc823..35c001f6aa79c2bef12c66bf8c3a131a42d2402e 100644 --- a/runtime/builtins/builtins_string.cpp +++ b/runtime/builtins/builtins_string.cpp @@ -36,7 +36,6 @@ #include "plugins/ecmascript/runtime/js_primitive_ref.h" #include "plugins/ecmascript/runtime/js_string_iterator.h" #include "plugins/ecmascript/runtime/js_tagged_value-inl.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "plugins/ecmascript/runtime/object_factory.h" #include "plugins/ecmascript/runtime/tagged_array-inl.h" #include "plugins/ecmascript/runtime/tagged_array.h" @@ -98,7 +97,7 @@ JSTaggedValue BuiltinsString::FromCharCode(EcmaRuntimeCallInfo *argv) return strHandle.GetTaggedValue(); } std::u16string u16str = ecmascript::base::StringHelper::Utf16ToU16String(&codePointValue, 1); - CVector valueTable; + PandaVector valueTable; valueTable.reserve(argLength - 1); for (int32_t i = 1; i < argLength; i++) { JSHandle nextCp = BuiltinsString::GetCallArg(argv, i); @@ -141,7 +140,7 @@ JSTaggedValue BuiltinsString::FromCodePoint(EcmaRuntimeCallInfo *argv) THROW_RANGE_ERROR_AND_RETURN(thread, "CodePoint < 0 or CodePoint > 0x10FFFF", JSTaggedValue::Exception()); } if (cp == 0) { - CVector data {0x00}; + PandaVector data {0x00}; return factory->NewFromUtf16Literal(data.data(), 1).GetTaggedValue(); } if (cp > UINT16_MAX) { diff --git a/runtime/builtins/builtins_typedarray.cpp b/runtime/builtins/builtins_typedarray.cpp index 113ef39e58ba4ee8b927039e01be55c535526315..fcbab7c481e3640b93cc6e23913a74fcd2a91437 100644 --- a/runtime/builtins/builtins_typedarray.cpp +++ b/runtime/builtins/builtins_typedarray.cpp @@ -155,7 +155,7 @@ JSTaggedValue BuiltinsTypedArray::From(EcmaRuntimeCallInfo *argv) // b. Let len be the number of elements in values. // c. Let targetObj be ? TypedArrayCreate(C, « len »). if (!usingIterator->IsUndefined()) { - CVector> vec; + PandaVector> vec; JSHandle iterator = JSIterator::GetIterator(thread, source, usingIterator); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); JSHandle next(thread, JSTaggedValue::True()); diff --git a/runtime/class_info_extractor.cpp b/runtime/class_info_extractor.cpp index 2c9c84dd45e676a6920c262fc851b00f2be1ac72..81f00ae84ee0bdc8408955a0901fd94c50a0a569 100644 --- a/runtime/class_info_extractor.cpp +++ b/runtime/class_info_extractor.cpp @@ -78,7 +78,7 @@ void ClassInfoExtractor::BuildClassInfoExtractorFromLiteral(JSThread *thread, JS } } else { // without static properties, set class name - CString clsName = extractor->GetConstructorMethod()->ParseFunctionName(); + PandaString clsName = extractor->GetConstructorMethod()->ParseFunctionName(); JSHandle clsNameHandle = factory->NewFromString(clsName); staticProperties->Set(thread, NAME_INDEX, clsNameHandle); } @@ -146,7 +146,7 @@ bool ClassInfoExtractor::ExtractAndReturnWhetherWithElements(JSThread *thread, c if (LIKELY(!keysHasNameFlag)) { [[maybe_unused]] EcmaHandleScope handleScope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - CString clsName = detail.ctorMethod->ParseFunctionName(); + PandaString clsName = detail.ctorMethod->ParseFunctionName(); JSHandle clsNameHandle = factory->NewFromString(clsName); properties->Set(thread, NAME_INDEX, clsNameHandle); } else { diff --git a/runtime/class_linker/panda_file_translator.cpp b/runtime/class_linker/panda_file_translator.cpp index f1a5d999fb953205d6313dc0b75a9c84bd612ab3..4d2259bdcd229104b07ab94538dade792372e66d 100644 --- a/runtime/class_linker/panda_file_translator.cpp +++ b/runtime/class_linker/panda_file_translator.cpp @@ -46,7 +46,7 @@ PandaFileTranslator::PandaFileTranslator(EcmaVM *vm) } JSHandle PandaFileTranslator::TranslatePandaFile(EcmaVM *vm, const panda_file::File &pf, - const CString &methodName) + const PandaString &methodName) { PandaFileTranslator translator(vm); translator.TranslateClasses(pf, methodName); @@ -76,7 +76,7 @@ const JSMethod *PandaFileTranslator::FindMethods(uint32_t offset) const return nullptr; } -void PandaFileTranslator::TranslateClasses(const panda_file::File &pf, const CString &methodName) +void PandaFileTranslator::TranslateClasses(const panda_file::File &pf, const PandaString &methodName) { Span classIndexes = pf.GetClasses(); methods_ = MakePandaUnique>(); diff --git a/runtime/class_linker/panda_file_translator.h b/runtime/class_linker/panda_file_translator.h index 4803cbc740cdb5087a6c9a7e97b74c2f4ced2a53..3aca4ffbc6aa8cc61231be36cbf1720758a55bfc 100644 --- a/runtime/class_linker/panda_file_translator.h +++ b/runtime/class_linker/panda_file_translator.h @@ -35,7 +35,7 @@ public: ~PandaFileTranslator() = default; NO_COPY_SEMANTIC(PandaFileTranslator); NO_MOVE_SEMANTIC(PandaFileTranslator); - static JSHandle TranslatePandaFile(EcmaVM *vm, const panda_file::File &pf, const CString &methodName); + static JSHandle TranslatePandaFile(EcmaVM *vm, const panda_file::File &pf, const PandaString &methodName); JSHandle DefineMethodInLiteral(uint32_t methodId, FunctionKind kind) const; static void QuickPandaFile(EcmaVM *vm, const panda_file::File &pf); @@ -92,7 +92,7 @@ private: uint32_t GetOrInsertConstantPool(ConstPoolType type, uint32_t offset); const JSMethod *FindMethods(uint32_t offset) const; Program *GenerateProgram(const panda_file::File &pf); - void TranslateClasses(const panda_file::File &pf, const CString &methodName); + void TranslateClasses(const panda_file::File &pf, const PandaString &methodName); void TranslateMethod(const compiler::AotClass &aot_class, const panda_file::File::StringData &sd, const panda_file::File &pf, const uint8_t *descriptor, panda_file::MethodDataAccessor &mda); void TranslateBytecode(uint32_t insSz, const uint8_t *insArr, const panda_file::File &pf, const JSMethod *method); diff --git a/runtime/class_linker/program_object-inl.h b/runtime/class_linker/program_object-inl.h index 47f284e12fd4e799c15b2d92343498b30ba0931e..51476d856b0d2ad67823f37d5590945e97435746 100644 --- a/runtime/class_linker/program_object-inl.h +++ b/runtime/class_linker/program_object-inl.h @@ -17,7 +17,6 @@ #define ECMASCRIPT_CLASS_LINKER_PROGRAM_INL_H #include "program_object.h" -#include "plugins/ecmascript/runtime/mem/region_factory.h" namespace panda::ecmascript { const uint8_t *LexicalFunction::GetInstructions() const diff --git a/runtime/class_linker/program_object.h b/runtime/class_linker/program_object.h index dd0bc09999cbeaf10879abda66b10d37c3ba49fe..a6fe0c1defe962905220d185c63ebecffc89de53 100644 --- a/runtime/class_linker/program_object.h +++ b/runtime/class_linker/program_object.h @@ -21,7 +21,6 @@ namespace panda::ecmascript { class JSThread; -class RegionFactory; class Program : public ECMAObject { public: diff --git a/runtime/dump.cpp b/runtime/dump.cpp index 50c6be37aa33e201629291c56bc2f281bd86f97f..6c79386fa51dbe4289702578331cfef59cca64be 100644 --- a/runtime/dump.cpp +++ b/runtime/dump.cpp @@ -71,9 +71,6 @@ #include "plugins/ecmascript/runtime/layout_info-inl.h" #include "plugins/ecmascript/runtime/lexical_env.h" #include "plugins/ecmascript/runtime/linked_hash_table-inl.h" -#include "plugins/ecmascript/runtime/mem/assert_scope-inl.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" -#include "plugins/ecmascript/runtime/mem/machine_code.h" #include "plugins/ecmascript/runtime/tagged_array.h" #include "plugins/ecmascript/runtime/tagged_dictionary.h" #include "plugins/ecmascript/runtime/template_map.h" @@ -86,7 +83,7 @@ using PendingJob = panda::ecmascript::job::PendingJob; static constexpr uint32_t DUMP_TYPE_OFFSET = 12; static constexpr uint32_t DUMP_PROPERTY_OFFSET = 20; -CString JSHClass::DumpJSType(JSType type) +PandaString JSHClass::DumpJSType(JSType type) { switch (type) { case JSType::HCLASS: @@ -270,7 +267,7 @@ CString JSHClass::DumpJSType(JSType type) case JSType::JS_ARRAY_LIST: return "ArrayList"; default: { - CString ret = "unknown type "; + PandaString ret = "unknown type "; return ret + static_cast(type); } } @@ -278,7 +275,6 @@ CString JSHClass::DumpJSType(JSType type) static void DumpArrayClass(JSThread *thread, const TaggedArray *arr, std::ostream &os) { - DISALLOW_GARBAGE_COLLECTION; uint32_t len = arr->GetLength(); os << " \n"; for (uint32_t i = 0; i < len; i++) { @@ -293,8 +289,7 @@ static void DumpArrayClass(JSThread *thread, const TaggedArray *arr, std::ostrea static void DumpStringClass(const EcmaString *str, std::ostream &os) { - DISALLOW_GARBAGE_COLLECTION; - CString string = ConvertToString(str); + PandaString string = ConvertToPandaString(str); os << string; } @@ -312,7 +307,6 @@ static void DumpPropertyKey(JSTaggedValue key, std::ostream &os) static void DumpHClass(JSThread *thread, const JSHClass *jshclass, std::ostream &os, bool withDetail) { - DISALLOW_GARBAGE_COLLECTION; os << "JSHClass :" << std::setw(DUMP_TYPE_OFFSET); os << "Type :" << JSHClass::DumpJSType(jshclass->GetObjectType()) << "\n"; @@ -389,7 +383,6 @@ static void DumpAttr(const PropertyAttributes &attr, bool fastMode, std::ostream // NOLINTNEXTLINE(readability-function-size) static void DumpObject(JSThread *thread, TaggedObject *obj, std::ostream &os) { - DISALLOW_GARBAGE_COLLECTION; auto jsHclass = obj->GetClass(); JSType type = jsHclass->GetObjectType(); @@ -679,12 +672,12 @@ void JSTaggedValue::DumpHeapObjectType([[maybe_unused]] JSThread *thread, std::o JSType type = GetTaggedObject()->GetClass()->GetObjectType(); if (type == JSType::STRING) { - CString string = ConvertToString(EcmaString::Cast(obj)); + PandaString string = ConvertToPandaString(EcmaString::Cast(obj)); os << std::left << std::setw(DUMP_TYPE_OFFSET) << "[" + string + "]"; } else { std::ostringstream address; address << obj; - CString addrStr = CString(address.str()); + PandaString addrStr = PandaString(address.str()); os << std::left << std::setw(DUMP_TYPE_OFFSET) << "[" + JSHClass::DumpJSType(type) + "(" + addrStr + ")]"; } @@ -735,7 +728,6 @@ void JSThread::DumpStack() void NumberDictionary::Dump(JSThread *thread, std::ostream &os) const { - DISALLOW_GARBAGE_COLLECTION; int size = Size(); for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); @@ -753,7 +745,6 @@ void NumberDictionary::Dump(JSThread *thread, std::ostream &os) const void NameDictionary::Dump(JSThread *thread, std::ostream &os) const { - DISALLOW_GARBAGE_COLLECTION; int size = Size(); for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); @@ -772,7 +763,6 @@ void NameDictionary::Dump(JSThread *thread, std::ostream &os) const void GlobalDictionary::Dump(JSThread *thread, std::ostream &os) const { - DISALLOW_GARBAGE_COLLECTION; int size = Size(); for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); @@ -791,7 +781,6 @@ void GlobalDictionary::Dump(JSThread *thread, std::ostream &os) const void LayoutInfo::Dump([[maybe_unused]] JSThread *thread, std::ostream &os) const { - DISALLOW_GARBAGE_COLLECTION; int num = NumberOfElements(); for (int i = 0; i < num; i++) { JSTaggedValue key = GetKey(i); @@ -807,7 +796,6 @@ void LayoutInfo::Dump([[maybe_unused]] JSThread *thread, std::ostream &os) const void TransitionsDictionary::Dump(JSThread *thread, std::ostream &os) const { - DISALLOW_GARBAGE_COLLECTION; int size = Size(); for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); @@ -825,7 +813,6 @@ void TransitionsDictionary::Dump(JSThread *thread, std::ostream &os) const void LinkedHashSet::Dump(JSThread *thread, std::ostream &os) const { - DISALLOW_GARBAGE_COLLECTION; int capacity = NumberOfElements() + NumberOfDeletedElements(); for (int hashIndex = 0; hashIndex < capacity; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); @@ -839,7 +826,6 @@ void LinkedHashSet::Dump(JSThread *thread, std::ostream &os) const void LinkedHashMap::Dump(JSThread *thread, std::ostream &os) const { - DISALLOW_GARBAGE_COLLECTION; int capacity = NumberOfElements() + NumberOfDeletedElements(); for (int hashIndex = 0; hashIndex < capacity; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); @@ -856,7 +842,6 @@ void LinkedHashMap::Dump(JSThread *thread, std::ostream &os) const void JSObject::Dump(JSThread *thread, std::ostream &os) const { - DISALLOW_GARBAGE_COLLECTION; JSHClass *jshclass = GetJSHClass(); os << " - hclass: " << std::hex << jshclass << "\n"; os << " - prototype: "; @@ -2012,35 +1997,33 @@ void ClassInfoExtractor::Dump([[maybe_unused]] JSThread *thread, std::ostream &o // Dump for Snapshot // ######################################################################################## static void DumpArrayClass([[maybe_unused]] JSThread *thread, const TaggedArray *arr, - std::vector> &vec) + std::vector> &vec) { - DISALLOW_GARBAGE_COLLECTION; uint32_t len = arr->GetLength(); for (uint32_t i = 0; i < len; i++) { JSTaggedValue val(arr->Get(i)); - CString str = ToCString(i); + PandaString str = ToPandaString(i); vec.emplace_back(std::make_pair(str, val)); } } static void DumpStringClass([[maybe_unused]] JSThread *thread, const EcmaString *str, - std::vector> &vec) + std::vector> &vec) { vec.emplace_back(std::make_pair("string", JSTaggedValue(str))); } static void DumpDynClass([[maybe_unused]] JSThread *thread, TaggedObject *obj, - std::vector> &vec) + std::vector> &vec) { JSHClass *jshclass = obj->GetClass(); vec.emplace_back(std::make_pair("__proto__", jshclass->GetPrototype())); } // NOLINTNEXTLINE(readability-function-size) -static void DumpObject(JSThread *thread, TaggedObject *obj, std::vector> &vec, +static void DumpObject(JSThread *thread, TaggedObject *obj, std::vector> &vec, bool isVmMode) { - DISALLOW_GARBAGE_COLLECTION; auto jsHclass = obj->GetClass(); JSType type = jsHclass->GetObjectType(); @@ -2281,18 +2264,18 @@ static void DumpObject(JSThread *thread, TaggedObject *obj, std::vectorGetLength() == 0) { - CString emptyStr = "EmptyString"; + PandaString emptyStr = "EmptyString"; res.append(emptyStr); } - CString string = ConvertToString(str); + PandaString string = ConvertToPandaString(str); res.append(string); } -static void KeyToStd(CString &res, JSTaggedValue key) +static void KeyToStd(PandaString &res, JSTaggedValue key) { if (key.IsInt()) { res = std::to_string(key.GetInt()); @@ -2313,7 +2296,7 @@ static void KeyToStd(CString &res, JSTaggedValue key) } } -void JSTaggedValue::DumpForSnapshot(JSThread *thread, std::vector> &vec, +void JSTaggedValue::DumpForSnapshot(JSThread *thread, std::vector> &vec, bool isVmMode) const { if (IsHeapObject()) { @@ -2324,30 +2307,28 @@ void JSTaggedValue::DumpForSnapshot(JSThread *thread, std::vector> &vec) const + std::vector> &vec) const { - DISALLOW_GARBAGE_COLLECTION; int size = Size(); for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); if (!key.IsUndefined() && !key.IsHole() && !key.IsNull()) { JSTaggedValue val(GetValue(hashIndex)); - CString str = ToCString(static_cast(JSTaggedNumber(key).GetNumber())); + PandaString str = ToPandaString(static_cast(JSTaggedNumber(key).GetNumber())); vec.emplace_back(std::make_pair(str, val)); } } } void NameDictionary::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - DISALLOW_GARBAGE_COLLECTION; int size = Size(); for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); if (!key.IsUndefined() && !key.IsHole() && !key.IsNull()) { JSTaggedValue val(GetValue(hashIndex)); - CString str; + PandaString str; KeyToStd(str, key); vec.emplace_back(std::make_pair(str, val)); } @@ -2355,14 +2336,13 @@ void NameDictionary::DumpForSnapshot([[maybe_unused]] JSThread *thread, } void GlobalDictionary::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - DISALLOW_GARBAGE_COLLECTION; int size = Size(); for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); if (!key.IsUndefined() && !key.IsHole() && !key.IsNull()) { - CString str; + PandaString str; KeyToStd(str, key); JSTaggedValue val = GetValue(hashIndex); vec.emplace_back(std::make_pair(str, val)); @@ -2371,14 +2351,13 @@ void GlobalDictionary::DumpForSnapshot([[maybe_unused]] JSThread *thread, } void LinkedHashSet::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - DISALLOW_GARBAGE_COLLECTION; int capacity = NumberOfElements() + NumberOfDeletedElements(); for (int hashIndex = 0; hashIndex < capacity; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); if (!key.IsUndefined() && !key.IsHole() && !key.IsNull()) { - CString str; + PandaString str; KeyToStd(str, key); vec.emplace_back(std::make_pair(str, JSTaggedValue::Hole())); } @@ -2386,24 +2365,22 @@ void LinkedHashSet::DumpForSnapshot([[maybe_unused]] JSThread *thread, } void LinkedHashMap::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - DISALLOW_GARBAGE_COLLECTION; int capacity = NumberOfElements() + NumberOfDeletedElements(); for (int hashIndex = 0; hashIndex < capacity; hashIndex++) { JSTaggedValue key(GetKey(hashIndex)); if (!key.IsUndefined() && !key.IsHole() && !key.IsNull()) { JSTaggedValue val = GetValue(hashIndex); - CString str; + PandaString str; KeyToStd(str, key); vec.emplace_back(std::make_pair(str, val)); } } } -void JSObject::DumpForSnapshot(JSThread *thread, std::vector> &vec) const +void JSObject::DumpForSnapshot(JSThread *thread, std::vector> &vec) const { - DISALLOW_GARBAGE_COLLECTION; JSHClass *jshclass = GetJSHClass(); vec.emplace_back(std::make_pair("__proto__", jshclass->GetPrototype())); @@ -2442,7 +2419,7 @@ void JSObject::DumpForSnapshot(JSThread *thread, std::vectorGet(i - jshclass->GetInlinedProperties()); } - CString str; + PandaString str; KeyToStd(str, key); vec.emplace_back(std::make_pair(str, val)); } @@ -2453,67 +2430,67 @@ void JSObject::DumpForSnapshot(JSThread *thread, std::vector> &vec) const + [[maybe_unused]] std::vector> &vec) const { } void JSFunction::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const -{ - vec.emplace_back(std::make_pair(CString("ProtoOrDynClass"), GetProtoOrDynClass())); - vec.emplace_back(std::make_pair(CString("LexicalEnv"), GetLexicalEnv())); - vec.emplace_back(std::make_pair(CString("HomeObject"), GetHomeObject())); - vec.emplace_back(std::make_pair(CString("FunctionInfoFlag"), GetFunctionInfoFlag())); - vec.emplace_back(std::make_pair(CString("FunctionExtraInfo"), GetFunctionExtraInfo())); - vec.emplace_back(std::make_pair(CString("ConstantPool"), GetConstantPool())); - vec.emplace_back(std::make_pair(CString("ProfileTypeInfo"), GetProfileTypeInfo())); + std::vector> &vec) const +{ + vec.emplace_back(std::make_pair(PandaString("ProtoOrDynClass"), GetProtoOrDynClass())); + vec.emplace_back(std::make_pair(PandaString("LexicalEnv"), GetLexicalEnv())); + vec.emplace_back(std::make_pair(PandaString("HomeObject"), GetHomeObject())); + vec.emplace_back(std::make_pair(PandaString("FunctionInfoFlag"), GetFunctionInfoFlag())); + vec.emplace_back(std::make_pair(PandaString("FunctionExtraInfo"), GetFunctionExtraInfo())); + vec.emplace_back(std::make_pair(PandaString("ConstantPool"), GetConstantPool())); + vec.emplace_back(std::make_pair(PandaString("ProfileTypeInfo"), GetProfileTypeInfo())); JSObject::DumpForSnapshot(thread, vec); } void Program::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("Location"), GetLocation())); - vec.emplace_back(std::make_pair(CString("ConstantPool"), GetConstantPool())); - vec.emplace_back(std::make_pair(CString("MainFunction"), GetMainFunction())); + vec.emplace_back(std::make_pair(PandaString("Location"), GetLocation())); + vec.emplace_back(std::make_pair(PandaString("ConstantPool"), GetConstantPool())); + vec.emplace_back(std::make_pair(PandaString("MainFunction"), GetMainFunction())); // MethodsData is another native field, and we don't dump it for JS heap. - vec.emplace_back(std::make_pair(CString("NumberMethods"), JSTaggedValue(GetMethodsData()->size()))); + vec.emplace_back(std::make_pair(PandaString("NumberMethods"), JSTaggedValue(GetMethodsData()->size()))); } void ConstantPool::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { DumpArrayClass(thread, this, vec); } void JSBoundFunction::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { JSObject::DumpForSnapshot(thread, vec); - vec.emplace_back(std::make_pair(CString("BoundTarget"), GetBoundTarget())); - vec.emplace_back(std::make_pair(CString("BoundThis"), GetBoundThis())); - vec.emplace_back(std::make_pair(CString("BoundArguments"), GetBoundArguments())); + vec.emplace_back(std::make_pair(PandaString("BoundTarget"), GetBoundTarget())); + vec.emplace_back(std::make_pair(PandaString("BoundThis"), GetBoundThis())); + vec.emplace_back(std::make_pair(PandaString("BoundArguments"), GetBoundArguments())); } void JSPrimitiveRef::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("subValue"), GetValue())); + vec.emplace_back(std::make_pair(PandaString("subValue"), GetValue())); JSObject::DumpForSnapshot(thread, vec); } void JSDate::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("time"), GetTime())); - vec.emplace_back(std::make_pair(CString("localOffset"), GetLocalOffset())); + vec.emplace_back(std::make_pair(PandaString("time"), GetTime())); + vec.emplace_back(std::make_pair(PandaString("localOffset"), GetLocalOffset())); JSObject::DumpForSnapshot(thread, vec); } void JSMap::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { LinkedHashMap *map = LinkedHashMap::Cast(GetLinkedMap().GetTaggedObject()); map->DumpForSnapshot(thread, vec); @@ -2522,27 +2499,27 @@ void JSMap::DumpForSnapshot([[maybe_unused]] JSThread *thread, } void JSForInIterator::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("Object"), GetObject())); - vec.emplace_back(std::make_pair(CString("WasVisited"), GetWasVisited())); - vec.emplace_back(std::make_pair(CString("VisitedKeys"), GetVisitedKeys())); - vec.emplace_back(std::make_pair(CString("RemainingKeys"), GetRemainingKeys())); + vec.emplace_back(std::make_pair(PandaString("Object"), GetObject())); + vec.emplace_back(std::make_pair(PandaString("WasVisited"), GetWasVisited())); + vec.emplace_back(std::make_pair(PandaString("VisitedKeys"), GetVisitedKeys())); + vec.emplace_back(std::make_pair(PandaString("RemainingKeys"), GetRemainingKeys())); JSObject::DumpForSnapshot(thread, vec); } void JSMapIterator::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { LinkedHashMap *map = LinkedHashMap::Cast(GetIteratedMap().GetTaggedObject()); map->DumpForSnapshot(thread, vec); - vec.emplace_back(std::make_pair(CString("NextIndex"), GetNextIndex())); - vec.emplace_back(std::make_pair(CString("IterationKind"), GetIterationKind())); + vec.emplace_back(std::make_pair(PandaString("NextIndex"), GetNextIndex())); + vec.emplace_back(std::make_pair(PandaString("IterationKind"), GetIterationKind())); JSObject::DumpForSnapshot(thread, vec); } void JSSet::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { LinkedHashSet *set = LinkedHashSet::Cast(GetLinkedSet().GetTaggedObject()); set->DumpForSnapshot(thread, vec); @@ -2551,7 +2528,7 @@ void JSSet::DumpForSnapshot([[maybe_unused]] JSThread *thread, } void JSWeakMap::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { LinkedHashMap *map = LinkedHashMap::Cast(GetLinkedMap().GetTaggedObject()); map->DumpForSnapshot(thread, vec); @@ -2560,7 +2537,7 @@ void JSWeakMap::DumpForSnapshot([[maybe_unused]] JSThread *thread, } void JSWeakSet::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { LinkedHashSet *set = LinkedHashSet::Cast(GetLinkedSet().GetTaggedObject()); set->DumpForSnapshot(thread, vec); @@ -2568,573 +2545,582 @@ void JSWeakSet::DumpForSnapshot([[maybe_unused]] JSThread *thread, JSObject::DumpForSnapshot(thread, vec); } void JSSetIterator::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { LinkedHashSet *set = LinkedHashSet::Cast(GetIteratedSet().GetTaggedObject()); set->DumpForSnapshot(thread, vec); - vec.emplace_back(std::make_pair(CString("NextIndex"), GetNextIndex())); - vec.emplace_back(std::make_pair(CString("IterationKind"), GetIterationKind())); + vec.emplace_back(std::make_pair(PandaString("NextIndex"), GetNextIndex())); + vec.emplace_back(std::make_pair(PandaString("IterationKind"), GetIterationKind())); JSObject::DumpForSnapshot(thread, vec); } void JSArray::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { JSObject::DumpForSnapshot(thread, vec); } void JSArrayList::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { JSObject::DumpForSnapshot(thread, vec); } void JSArrayIterator::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { JSArray *array = JSArray::Cast(GetIteratedArray().GetTaggedObject()); array->DumpForSnapshot(thread, vec); - vec.emplace_back(std::make_pair(CString("NextIndex"), GetNextIndex())); - vec.emplace_back(std::make_pair(CString("IterationKind"), GetIterationKind())); + vec.emplace_back(std::make_pair(PandaString("NextIndex"), GetNextIndex())); + vec.emplace_back(std::make_pair(PandaString("IterationKind"), GetIterationKind())); JSObject::DumpForSnapshot(thread, vec); } void JSStringIterator::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("IteratedString"), GetIteratedString())); - vec.emplace_back(std::make_pair(CString("StringIteratorNextIndex"), GetStringIteratorNextIndex())); + vec.emplace_back(std::make_pair(PandaString("IteratedString"), GetIteratedString())); + vec.emplace_back(std::make_pair(PandaString("StringIteratorNextIndex"), GetStringIteratorNextIndex())); JSObject::DumpForSnapshot(thread, vec); } void JSTypedArray::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("viewed-array-buffer"), GetViewedArrayBuffer())); - vec.emplace_back(std::make_pair(CString("typed-array-name"), GetTypedArrayName())); - vec.emplace_back(std::make_pair(CString("byte-length"), GetByteLength())); - vec.emplace_back(std::make_pair(CString("byte-offset"), GetByteOffset())); - vec.emplace_back(std::make_pair(CString("array-length"), GetArrayLength())); + vec.emplace_back(std::make_pair(PandaString("viewed-array-buffer"), GetViewedArrayBuffer())); + vec.emplace_back(std::make_pair(PandaString("typed-array-name"), GetTypedArrayName())); + vec.emplace_back(std::make_pair(PandaString("byte-length"), GetByteLength())); + vec.emplace_back(std::make_pair(PandaString("byte-offset"), GetByteOffset())); + vec.emplace_back(std::make_pair(PandaString("array-length"), GetArrayLength())); } void JSRegExp::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("originalSource"), GetOriginalSource())); - vec.emplace_back(std::make_pair(CString("originalFlags"), GetOriginalFlags())); + vec.emplace_back(std::make_pair(PandaString("originalSource"), GetOriginalSource())); + vec.emplace_back(std::make_pair(PandaString("originalFlags"), GetOriginalFlags())); JSObject::DumpForSnapshot(thread, vec); } void JSProxy::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("target"), GetTarget())); - vec.emplace_back(std::make_pair(CString("handler"), GetHandler())); + vec.emplace_back(std::make_pair(PandaString("target"), GetTarget())); + vec.emplace_back(std::make_pair(PandaString("handler"), GetHandler())); } void JSSymbol::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("hash-field"), GetHashField())); - vec.emplace_back(std::make_pair(CString("flags"), GetFlags())); - vec.emplace_back(std::make_pair(CString("description"), GetDescription())); + vec.emplace_back(std::make_pair(PandaString("hash-field"), GetHashField())); + vec.emplace_back(std::make_pair(PandaString("flags"), GetFlags())); + vec.emplace_back(std::make_pair(PandaString("description"), GetDescription())); } void AccessorData::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("getter"), GetGetter())); - vec.emplace_back(std::make_pair(CString("setter"), GetSetter())); + vec.emplace_back(std::make_pair(PandaString("getter"), GetGetter())); + vec.emplace_back(std::make_pair(PandaString("setter"), GetSetter())); } void LexicalEnv::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { DumpArrayClass(thread, this, vec); } void GlobalEnv::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { auto globalConst = thread->GlobalConstants(); - vec.emplace_back(std::make_pair(CString("ObjectFunction"), GetObjectFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("FunctionFunction"), GetFunctionFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("NumberFunction"), GetNumberFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("DateFunction"), GetDateFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("BooleanFunction"), GetBooleanFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("ErrorFunction"), GetErrorFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("ArrayFunction"), GetArrayFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("TypedArrayFunction"), GetTypedArrayFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("Int8ArrayFunction"), GetInt8ArrayFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("Uint8ArrayFunction"), GetUint8ArrayFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("ObjectFunction"), GetObjectFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("FunctionFunction"), GetFunctionFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("NumberFunction"), GetNumberFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("DateFunction"), GetDateFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("BooleanFunction"), GetBooleanFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("ErrorFunction"), GetErrorFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("ArrayFunction"), GetArrayFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("TypedArrayFunction"), GetTypedArrayFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("Int8ArrayFunction"), GetInt8ArrayFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("Uint8ArrayFunction"), GetUint8ArrayFunction().GetTaggedValue())); vec.emplace_back( - std::make_pair(CString("Uint8ClampedArrayFunction"), GetUint8ClampedArrayFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("Int16ArrayFunction"), GetInt16ArrayFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("Uint16ArrayFunction"), GetUint16ArrayFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("Int32ArrayFunction"), GetInt32ArrayFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("Uint32ArrayFunction"), GetUint32ArrayFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("Float32ArrayFunction"), GetFloat32ArrayFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("Float64ArrayFunction"), GetFloat64ArrayFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("ArrayBufferFunction"), GetArrayBufferFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("SymbolFunction"), GetSymbolFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("RangeErrorFunction"), GetRangeErrorFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("ReferenceErrorFunction"), GetReferenceErrorFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("TypeErrorFunction"), GetTypeErrorFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("URIErrorFunction"), GetURIErrorFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("SyntaxErrorFunction"), GetSyntaxErrorFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("EvalErrorFunction"), GetEvalErrorFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("RegExpFunction"), GetRegExpFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("BuiltinsSetFunction"), GetBuiltinsSetFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("BuiltinsMapFunction"), GetBuiltinsMapFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("BuiltinsWeakSetFunction"), GetBuiltinsWeakSetFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("BuiltinsWeakMapFunction"), GetBuiltinsWeakMapFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("MathFunction"), GetMathFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("JsonFunction"), GetJsonFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("StringFunction"), GetStringFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("ProxyFunction"), GetProxyFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("ReflectFunction"), GetReflectFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("AsyncFunction"), GetAsyncFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("AsyncFunctionPrototype"), GetAsyncFunctionPrototype().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("JSGlobalObject"), GetJSGlobalObject().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("EmptyArray"), GetEmptyArray().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("EmptyString"), globalConst->GetEmptyString())); - vec.emplace_back(std::make_pair(CString("EmptyTaggedQueue"), GetEmptyTaggedQueue().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("PrototypeString"), globalConst->GetPrototypeString())); - vec.emplace_back(std::make_pair(CString("HasInstanceSymbol"), GetHasInstanceSymbol().GetTaggedValue())); + std::make_pair(PandaString("Uint8ClampedArrayFunction"), GetUint8ClampedArrayFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("Int16ArrayFunction"), GetInt16ArrayFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("Uint16ArrayFunction"), GetUint16ArrayFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("Int32ArrayFunction"), GetInt32ArrayFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("Uint32ArrayFunction"), GetUint32ArrayFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("Float32ArrayFunction"), GetFloat32ArrayFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("Float64ArrayFunction"), GetFloat64ArrayFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("ArrayBufferFunction"), GetArrayBufferFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("SymbolFunction"), GetSymbolFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("RangeErrorFunction"), GetRangeErrorFunction().GetTaggedValue())); vec.emplace_back( - std::make_pair(CString("IsConcatSpreadableSymbol"), GetIsConcatSpreadableSymbol().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("ToStringTagSymbol"), GetToStringTagSymbol().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("IteratorSymbol"), GetIteratorSymbol().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("MatchSymbol"), GetMatchSymbol().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("ReplaceSymbol"), GetReplaceSymbol().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("SearchSymbol"), GetSearchSymbol().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("SpeciesSymbol"), GetSpeciesSymbol().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("SplitSymbol"), GetSplitSymbol().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("ToPrimitiveSymbol"), GetToPrimitiveSymbol().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("UnscopablesSymbol"), GetUnscopablesSymbol().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("HoleySymbol"), GetHoleySymbol().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("ConstructorString"), globalConst->GetConstructorString())); - vec.emplace_back(std::make_pair(CString("IteratorPrototype"), GetIteratorPrototype().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("ForinIteratorPrototype"), GetForinIteratorPrototype().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("StringIterator"), GetStringIterator().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("MapIteratorPrototype"), GetMapIteratorPrototype().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("SetIteratorPrototype"), GetSetIteratorPrototype().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("ArrayIteratorPrototype"), GetArrayIteratorPrototype().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("StringIteratorPrototype"), GetStringIteratorPrototype().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("LengthString"), globalConst->GetLengthString())); - vec.emplace_back(std::make_pair(CString("ValueString"), globalConst->GetValueString())); - vec.emplace_back(std::make_pair(CString("WritableString"), globalConst->GetWritableString())); - vec.emplace_back(std::make_pair(CString("GetString"), globalConst->GetGetString())); - vec.emplace_back(std::make_pair(CString("SetString"), globalConst->GetSetString())); - vec.emplace_back(std::make_pair(CString("EnumerableString"), globalConst->GetEnumerableString())); - vec.emplace_back(std::make_pair(CString("ConfigurableString"), globalConst->GetConfigurableString())); - vec.emplace_back(std::make_pair(CString("NameString"), globalConst->GetNameString())); - vec.emplace_back(std::make_pair(CString("ValueOfString"), globalConst->GetValueOfString())); - vec.emplace_back(std::make_pair(CString("ToStringString"), globalConst->GetToStringString())); - vec.emplace_back(std::make_pair(CString("ToLocaleStringString"), globalConst->GetToLocaleStringString())); - vec.emplace_back(std::make_pair(CString("UndefinedString"), globalConst->GetUndefinedString())); - vec.emplace_back(std::make_pair(CString("NullString"), globalConst->GetNullString())); - vec.emplace_back(std::make_pair(CString("TrueString"), globalConst->GetTrueString())); - vec.emplace_back(std::make_pair(CString("FalseString"), globalConst->GetFalseString())); - vec.emplace_back(std::make_pair(CString("RegisterSymbols"), GetRegisterSymbols().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("ThrowTypeError"), GetThrowTypeError().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("GetPrototypeOfString"), globalConst->GetGetPrototypeOfString())); - vec.emplace_back(std::make_pair(CString("SetPrototypeOfString"), globalConst->GetSetPrototypeOfString())); - vec.emplace_back(std::make_pair(CString("IsExtensibleString"), globalConst->GetIsExtensibleString())); - vec.emplace_back(std::make_pair(CString("PreventExtensionsString"), globalConst->GetPreventExtensionsString())); + std::make_pair(PandaString("ReferenceErrorFunction"), GetReferenceErrorFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("TypeErrorFunction"), GetTypeErrorFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("URIErrorFunction"), GetURIErrorFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("SyntaxErrorFunction"), GetSyntaxErrorFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("EvalErrorFunction"), GetEvalErrorFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("RegExpFunction"), GetRegExpFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("BuiltinsSetFunction"), GetBuiltinsSetFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("BuiltinsMapFunction"), GetBuiltinsMapFunction().GetTaggedValue())); vec.emplace_back( - std::make_pair(CString("GetOwnPropertyDescriptorString"), globalConst->GetGetOwnPropertyDescriptorString())); - vec.emplace_back(std::make_pair(CString("DefinePropertyString"), globalConst->GetDefinePropertyString())); - vec.emplace_back(std::make_pair(CString("HasString"), globalConst->GetHasString())); - vec.emplace_back(std::make_pair(CString("DeletePropertyString"), globalConst->GetDeletePropertyString())); - vec.emplace_back(std::make_pair(CString("EnumerateString"), globalConst->GetEnumerateString())); - vec.emplace_back(std::make_pair(CString("OwnKeysString"), globalConst->GetOwnKeysString())); - vec.emplace_back(std::make_pair(CString("ApplyString"), globalConst->GetApplyString())); - vec.emplace_back(std::make_pair(CString("ProxyString"), globalConst->GetProxyString())); - vec.emplace_back(std::make_pair(CString("RevokeString"), globalConst->GetRevokeString())); - vec.emplace_back(std::make_pair(CString("ProxyConstructString"), globalConst->GetProxyConstructString())); - vec.emplace_back(std::make_pair(CString("ProxyCallString"), globalConst->GetProxyCallString())); - vec.emplace_back(std::make_pair(CString("DoneString"), globalConst->GetDoneString())); - vec.emplace_back(std::make_pair(CString("NegativeZeroString"), globalConst->GetNegativeZeroString())); - vec.emplace_back(std::make_pair(CString("NextString"), globalConst->GetNextString())); - vec.emplace_back(std::make_pair(CString("PromiseThenString"), globalConst->GetPromiseThenString())); - vec.emplace_back(std::make_pair(CString("PromiseFunction"), GetPromiseFunction().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("PromiseReactionJob"), GetPromiseReactionJob().GetTaggedValue())); + std::make_pair(PandaString("BuiltinsWeakSetFunction"), GetBuiltinsWeakSetFunction().GetTaggedValue())); vec.emplace_back( - std::make_pair(CString("PromiseResolveThenableJob"), GetPromiseResolveThenableJob().GetTaggedValue())); - vec.emplace_back(std::make_pair(CString("ScriptJobString"), globalConst->GetScriptJobString())); - vec.emplace_back(std::make_pair(CString("PromiseString"), globalConst->GetPromiseString())); - vec.emplace_back(std::make_pair(CString("IdentityString"), globalConst->GetIdentityString())); - vec.emplace_back(std::make_pair(CString("AsyncFunctionString"), globalConst->GetAsyncFunctionString())); - vec.emplace_back(std::make_pair(CString("ThrowerString"), globalConst->GetThrowerString())); - vec.emplace_back(std::make_pair(CString("Undefined"), globalConst->GetUndefined())); + std::make_pair(PandaString("BuiltinsWeakMapFunction"), GetBuiltinsWeakMapFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("MathFunction"), GetMathFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("JsonFunction"), GetJsonFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("StringFunction"), GetStringFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("ProxyFunction"), GetProxyFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("ReflectFunction"), GetReflectFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("AsyncFunction"), GetAsyncFunction().GetTaggedValue())); + vec.emplace_back( + std::make_pair(PandaString("AsyncFunctionPrototype"), GetAsyncFunctionPrototype().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("JSGlobalObject"), GetJSGlobalObject().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("EmptyArray"), GetEmptyArray().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("EmptyString"), globalConst->GetEmptyString())); + vec.emplace_back(std::make_pair(PandaString("EmptyTaggedQueue"), GetEmptyTaggedQueue().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("PrototypeString"), globalConst->GetPrototypeString())); + vec.emplace_back(std::make_pair(PandaString("HasInstanceSymbol"), GetHasInstanceSymbol().GetTaggedValue())); + vec.emplace_back( + std::make_pair(PandaString("IsConcatSpreadableSymbol"), GetIsConcatSpreadableSymbol().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("ToStringTagSymbol"), GetToStringTagSymbol().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("IteratorSymbol"), GetIteratorSymbol().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("MatchSymbol"), GetMatchSymbol().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("ReplaceSymbol"), GetReplaceSymbol().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("SearchSymbol"), GetSearchSymbol().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("SpeciesSymbol"), GetSpeciesSymbol().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("SplitSymbol"), GetSplitSymbol().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("ToPrimitiveSymbol"), GetToPrimitiveSymbol().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("UnscopablesSymbol"), GetUnscopablesSymbol().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("HoleySymbol"), GetHoleySymbol().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("ConstructorString"), globalConst->GetConstructorString())); + vec.emplace_back(std::make_pair(PandaString("IteratorPrototype"), GetIteratorPrototype().GetTaggedValue())); + vec.emplace_back( + std::make_pair(PandaString("ForinIteratorPrototype"), GetForinIteratorPrototype().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("StringIterator"), GetStringIterator().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("MapIteratorPrototype"), GetMapIteratorPrototype().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("SetIteratorPrototype"), GetSetIteratorPrototype().GetTaggedValue())); + vec.emplace_back( + std::make_pair(PandaString("ArrayIteratorPrototype"), GetArrayIteratorPrototype().GetTaggedValue())); + vec.emplace_back( + std::make_pair(PandaString("StringIteratorPrototype"), GetStringIteratorPrototype().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("LengthString"), globalConst->GetLengthString())); + vec.emplace_back(std::make_pair(PandaString("ValueString"), globalConst->GetValueString())); + vec.emplace_back(std::make_pair(PandaString("WritableString"), globalConst->GetWritableString())); + vec.emplace_back(std::make_pair(PandaString("GetString"), globalConst->GetGetString())); + vec.emplace_back(std::make_pair(PandaString("SetString"), globalConst->GetSetString())); + vec.emplace_back(std::make_pair(PandaString("EnumerableString"), globalConst->GetEnumerableString())); + vec.emplace_back(std::make_pair(PandaString("ConfigurableString"), globalConst->GetConfigurableString())); + vec.emplace_back(std::make_pair(PandaString("NameString"), globalConst->GetNameString())); + vec.emplace_back(std::make_pair(PandaString("ValueOfString"), globalConst->GetValueOfString())); + vec.emplace_back(std::make_pair(PandaString("ToStringString"), globalConst->GetToStringString())); + vec.emplace_back(std::make_pair(PandaString("ToLocaleStringString"), globalConst->GetToLocaleStringString())); + vec.emplace_back(std::make_pair(PandaString("UndefinedString"), globalConst->GetUndefinedString())); + vec.emplace_back(std::make_pair(PandaString("NullString"), globalConst->GetNullString())); + vec.emplace_back(std::make_pair(PandaString("TrueString"), globalConst->GetTrueString())); + vec.emplace_back(std::make_pair(PandaString("FalseString"), globalConst->GetFalseString())); + vec.emplace_back(std::make_pair(PandaString("RegisterSymbols"), GetRegisterSymbols().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("ThrowTypeError"), GetThrowTypeError().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("GetPrototypeOfString"), globalConst->GetGetPrototypeOfString())); + vec.emplace_back(std::make_pair(PandaString("SetPrototypeOfString"), globalConst->GetSetPrototypeOfString())); + vec.emplace_back(std::make_pair(PandaString("IsExtensibleString"), globalConst->GetIsExtensibleString())); + vec.emplace_back(std::make_pair(PandaString("PreventExtensionsString"), globalConst->GetPreventExtensionsString())); + vec.emplace_back(std::make_pair(PandaString("GetOwnPropertyDescriptorString"), + globalConst->GetGetOwnPropertyDescriptorString())); + vec.emplace_back(std::make_pair(PandaString("DefinePropertyString"), globalConst->GetDefinePropertyString())); + vec.emplace_back(std::make_pair(PandaString("HasString"), globalConst->GetHasString())); + vec.emplace_back(std::make_pair(PandaString("DeletePropertyString"), globalConst->GetDeletePropertyString())); + vec.emplace_back(std::make_pair(PandaString("EnumerateString"), globalConst->GetEnumerateString())); + vec.emplace_back(std::make_pair(PandaString("OwnKeysString"), globalConst->GetOwnKeysString())); + vec.emplace_back(std::make_pair(PandaString("ApplyString"), globalConst->GetApplyString())); + vec.emplace_back(std::make_pair(PandaString("ProxyString"), globalConst->GetProxyString())); + vec.emplace_back(std::make_pair(PandaString("RevokeString"), globalConst->GetRevokeString())); + vec.emplace_back(std::make_pair(PandaString("ProxyConstructString"), globalConst->GetProxyConstructString())); + vec.emplace_back(std::make_pair(PandaString("ProxyCallString"), globalConst->GetProxyCallString())); + vec.emplace_back(std::make_pair(PandaString("DoneString"), globalConst->GetDoneString())); + vec.emplace_back(std::make_pair(PandaString("NegativeZeroString"), globalConst->GetNegativeZeroString())); + vec.emplace_back(std::make_pair(PandaString("NextString"), globalConst->GetNextString())); + vec.emplace_back(std::make_pair(PandaString("PromiseThenString"), globalConst->GetPromiseThenString())); + vec.emplace_back(std::make_pair(PandaString("PromiseFunction"), GetPromiseFunction().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("PromiseReactionJob"), GetPromiseReactionJob().GetTaggedValue())); + vec.emplace_back( + std::make_pair(PandaString("PromiseResolveThenableJob"), GetPromiseResolveThenableJob().GetTaggedValue())); + vec.emplace_back(std::make_pair(PandaString("ScriptJobString"), globalConst->GetScriptJobString())); + vec.emplace_back(std::make_pair(PandaString("PromiseString"), globalConst->GetPromiseString())); + vec.emplace_back(std::make_pair(PandaString("IdentityString"), globalConst->GetIdentityString())); + vec.emplace_back(std::make_pair(PandaString("AsyncFunctionString"), globalConst->GetAsyncFunctionString())); + vec.emplace_back(std::make_pair(PandaString("ThrowerString"), globalConst->GetThrowerString())); + vec.emplace_back(std::make_pair(PandaString("Undefined"), globalConst->GetUndefined())); } void JSDataView::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("data-view"), GetDataView())); - vec.emplace_back(std::make_pair(CString("buffer"), GetViewedArrayBuffer())); - vec.emplace_back(std::make_pair(CString("byte-length"), GetByteLength())); - vec.emplace_back(std::make_pair(CString("byte-offset"), GetByteOffset())); + vec.emplace_back(std::make_pair(PandaString("data-view"), GetDataView())); + vec.emplace_back(std::make_pair(PandaString("buffer"), GetViewedArrayBuffer())); + vec.emplace_back(std::make_pair(PandaString("byte-length"), GetByteLength())); + vec.emplace_back(std::make_pair(PandaString("byte-offset"), GetByteOffset())); } void JSArrayBuffer::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("byte-length"), GetArrayBufferByteLength())); - vec.emplace_back(std::make_pair(CString("buffer-data"), GetArrayBufferData())); - vec.emplace_back(std::make_pair(CString("shared"), GetShared())); + vec.emplace_back(std::make_pair(PandaString("byte-length"), GetArrayBufferByteLength())); + vec.emplace_back(std::make_pair(PandaString("buffer-data"), GetArrayBufferData())); + vec.emplace_back(std::make_pair(PandaString("shared"), GetShared())); } void PromiseReaction::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("promise-capability"), GetPromiseCapability())); - vec.emplace_back(std::make_pair(CString("type"), GetType())); - vec.emplace_back(std::make_pair(CString("handler"), GetHandler())); + vec.emplace_back(std::make_pair(PandaString("promise-capability"), GetPromiseCapability())); + vec.emplace_back(std::make_pair(PandaString("type"), GetType())); + vec.emplace_back(std::make_pair(PandaString("handler"), GetHandler())); } void PromiseCapability::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("promise"), GetPromise())); - vec.emplace_back(std::make_pair(CString("resolve"), GetResolve())); - vec.emplace_back(std::make_pair(CString("reject"), GetReject())); + vec.emplace_back(std::make_pair(PandaString("promise"), GetPromise())); + vec.emplace_back(std::make_pair(PandaString("resolve"), GetResolve())); + vec.emplace_back(std::make_pair(PandaString("reject"), GetReject())); } void PromiseIteratorRecord::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("iterator"), GetIterator())); - vec.emplace_back(std::make_pair(CString("done"), GetDone())); + vec.emplace_back(std::make_pair(PandaString("iterator"), GetIterator())); + vec.emplace_back(std::make_pair(PandaString("done"), GetDone())); } void PromiseRecord::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("value"), GetValue())); + vec.emplace_back(std::make_pair(PandaString("value"), GetValue())); } void ResolvingFunctionsRecord::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("resolve-function"), GetResolveFunction())); - vec.emplace_back(std::make_pair(CString("reject-function"), GetRejectFunction())); + vec.emplace_back(std::make_pair(PandaString("resolve-function"), GetResolveFunction())); + vec.emplace_back(std::make_pair(PandaString("reject-function"), GetRejectFunction())); } void JSPromise::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("promise-state"), GetPromiseState())); - vec.emplace_back(std::make_pair(CString("promise-result"), GetPromiseResult())); - vec.emplace_back(std::make_pair(CString("promise-fulfill-reactions"), GetPromiseFulfillReactions())); - vec.emplace_back(std::make_pair(CString("promise-reject-reactions"), GetPromiseRejectReactions())); - vec.emplace_back(std::make_pair(CString("promise-is-handled"), GetPromiseIsHandled())); + vec.emplace_back(std::make_pair(PandaString("promise-state"), GetPromiseState())); + vec.emplace_back(std::make_pair(PandaString("promise-result"), GetPromiseResult())); + vec.emplace_back(std::make_pair(PandaString("promise-fulfill-reactions"), GetPromiseFulfillReactions())); + vec.emplace_back(std::make_pair(PandaString("promise-reject-reactions"), GetPromiseRejectReactions())); + vec.emplace_back(std::make_pair(PandaString("promise-is-handled"), GetPromiseIsHandled())); JSObject::DumpForSnapshot(thread, vec); } void JSPromiseReactionsFunction::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("promise"), GetPromise())); - vec.emplace_back(std::make_pair(CString("already-resolved"), GetAlreadyResolved())); + vec.emplace_back(std::make_pair(PandaString("promise"), GetPromise())); + vec.emplace_back(std::make_pair(PandaString("already-resolved"), GetAlreadyResolved())); JSObject::DumpForSnapshot(thread, vec); } void JSPromiseExecutorFunction::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("capability"), GetCapability())); + vec.emplace_back(std::make_pair(PandaString("capability"), GetCapability())); JSObject::DumpForSnapshot(thread, vec); } void JSPromiseAllResolveElementFunction::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("index"), GetIndex())); - vec.emplace_back(std::make_pair(CString("values"), GetValues())); - vec.emplace_back(std::make_pair(CString("capabilities"), GetCapabilities())); - vec.emplace_back(std::make_pair(CString("remaining-elements"), GetRemainingElements())); - vec.emplace_back(std::make_pair(CString("already-called"), GetAlreadyCalled())); + vec.emplace_back(std::make_pair(PandaString("index"), GetIndex())); + vec.emplace_back(std::make_pair(PandaString("values"), GetValues())); + vec.emplace_back(std::make_pair(PandaString("capabilities"), GetCapabilities())); + vec.emplace_back(std::make_pair(PandaString("remaining-elements"), GetRemainingElements())); + vec.emplace_back(std::make_pair(PandaString("already-called"), GetAlreadyCalled())); JSObject::DumpForSnapshot(thread, vec); } void MicroJobQueue::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("promise-job-queue"), GetPromiseJobQueue())); - vec.emplace_back(std::make_pair(CString("script-job-queue"), GetScriptJobQueue())); + vec.emplace_back(std::make_pair(PandaString("promise-job-queue"), GetPromiseJobQueue())); + vec.emplace_back(std::make_pair(PandaString("script-job-queue"), GetScriptJobQueue())); } void PendingJob::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("job"), GetJob())); - vec.emplace_back(std::make_pair(CString("arguments"), GetArguments())); + vec.emplace_back(std::make_pair(PandaString("job"), GetJob())); + vec.emplace_back(std::make_pair(PandaString("arguments"), GetArguments())); } void CompletionRecord::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("type"), GetType())); - vec.emplace_back(std::make_pair(CString("value"), GetValue())); + vec.emplace_back(std::make_pair(PandaString("type"), GetType())); + vec.emplace_back(std::make_pair(PandaString("value"), GetValue())); } void JSProxyRevocFunction::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("RevocableProxy"), GetRevocableProxy())); + vec.emplace_back(std::make_pair(PandaString("RevocableProxy"), GetRevocableProxy())); } void JSAsyncFunction::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { JSFunction::DumpForSnapshot(thread, vec); } void JSAsyncGeneratorResolveNextFunction::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("AsyncGenerator"), GetAsyncGenerator())); + vec.emplace_back(std::make_pair(PandaString("AsyncGenerator"), GetAsyncGenerator())); } void JSAsyncFromSyncIteratorValueUnwrapFunction::DumpForSnapshot( - [[maybe_unused]] JSThread *thread, std::vector> &vec) const + [[maybe_unused]] JSThread *thread, std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("done"), GetDone())); + vec.emplace_back(std::make_pair(PandaString("done"), GetDone())); } void JSAsyncAwaitStatusFunction::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("AsyncContext"), GetAsyncContext())); + vec.emplace_back(std::make_pair(PandaString("AsyncContext"), GetAsyncContext())); } void JSGeneratorFunction::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { JSFunction::DumpForSnapshot(thread, vec); } -void JSIntlBoundFunction::DumpForSnapshot(JSThread *thread, std::vector> &vec) const +void JSIntlBoundFunction::DumpForSnapshot(JSThread *thread, + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("NumberFormat"), GetNumberFormat())); - vec.emplace_back(std::make_pair(CString("DateTimeFormat"), GetDateTimeFormat())); - vec.emplace_back(std::make_pair(CString("Collator"), GetCollator())); + vec.emplace_back(std::make_pair(PandaString("NumberFormat"), GetNumberFormat())); + vec.emplace_back(std::make_pair(PandaString("DateTimeFormat"), GetDateTimeFormat())); + vec.emplace_back(std::make_pair(PandaString("Collator"), GetCollator())); JSObject::DumpForSnapshot(thread, vec); } void PropertyBox::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("Value"), GetValue())); + vec.emplace_back(std::make_pair(PandaString("Value"), GetValue())); } void PrototypeHandler::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("HandlerInfo"), GetHandlerInfo())); - vec.emplace_back(std::make_pair(CString("ProtoCell"), GetProtoCell())); - vec.emplace_back(std::make_pair(CString("Holder"), GetHolder())); + vec.emplace_back(std::make_pair(PandaString("HandlerInfo"), GetHandlerInfo())); + vec.emplace_back(std::make_pair(PandaString("ProtoCell"), GetProtoCell())); + vec.emplace_back(std::make_pair(PandaString("Holder"), GetHolder())); } void TransitionHandler::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("HandlerInfo"), GetHandlerInfo())); - vec.emplace_back(std::make_pair(CString("TransitionHClass"), GetTransitionHClass())); + vec.emplace_back(std::make_pair(PandaString("HandlerInfo"), GetHandlerInfo())); + vec.emplace_back(std::make_pair(PandaString("TransitionHClass"), GetTransitionHClass())); } void JSRealm::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("Value"), GetValue())); - vec.emplace_back(std::make_pair(CString("GLobalEnv"), GetGlobalEnv())); + vec.emplace_back(std::make_pair(PandaString("Value"), GetValue())); + vec.emplace_back(std::make_pair(PandaString("GLobalEnv"), GetGlobalEnv())); JSObject::DumpForSnapshot(thread, vec); } -void JSIntl::DumpForSnapshot(JSThread *thread, std::vector> &vec) const +void JSIntl::DumpForSnapshot(JSThread *thread, std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("FallbackSymbol"), GetFallbackSymbol())); + vec.emplace_back(std::make_pair(PandaString("FallbackSymbol"), GetFallbackSymbol())); JSObject::DumpForSnapshot(thread, vec); } -void JSLocale::DumpForSnapshot(JSThread *thread, std::vector> &vec) const +void JSLocale::DumpForSnapshot(JSThread *thread, std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("IcuField"), GetIcuField())); + vec.emplace_back(std::make_pair(PandaString("IcuField"), GetIcuField())); JSObject::DumpForSnapshot(thread, vec); } -void JSDateTimeFormat::DumpForSnapshot(JSThread *thread, std::vector> &vec) const +void JSDateTimeFormat::DumpForSnapshot(JSThread *thread, std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("Locale"), GetLocale())); - vec.emplace_back(std::make_pair(CString("Calendar"), GetCalendar())); - vec.emplace_back(std::make_pair(CString("NumberingSystem"), GetNumberingSystem())); - vec.emplace_back(std::make_pair(CString("TimeZone"), GetTimeZone())); - vec.emplace_back(std::make_pair(CString("HourCycle"), GetHourCycle())); - vec.emplace_back(std::make_pair(CString("LocaleIcu"), GetLocaleIcu())); - vec.emplace_back(std::make_pair(CString("SimpleDateTimeFormatIcu"), GetSimpleDateTimeFormatIcu())); - vec.emplace_back(std::make_pair(CString("Iso8601"), GetIso8601())); - vec.emplace_back(std::make_pair(CString("DateStyle"), GetDateStyle())); - vec.emplace_back(std::make_pair(CString("TimeStyle"), GetTimeStyle())); - vec.emplace_back(std::make_pair(CString("BoundFormat"), GetBoundFormat())); + vec.emplace_back(std::make_pair(PandaString("Locale"), GetLocale())); + vec.emplace_back(std::make_pair(PandaString("Calendar"), GetCalendar())); + vec.emplace_back(std::make_pair(PandaString("NumberingSystem"), GetNumberingSystem())); + vec.emplace_back(std::make_pair(PandaString("TimeZone"), GetTimeZone())); + vec.emplace_back(std::make_pair(PandaString("HourCycle"), GetHourCycle())); + vec.emplace_back(std::make_pair(PandaString("LocaleIcu"), GetLocaleIcu())); + vec.emplace_back(std::make_pair(PandaString("SimpleDateTimeFormatIcu"), GetSimpleDateTimeFormatIcu())); + vec.emplace_back(std::make_pair(PandaString("Iso8601"), GetIso8601())); + vec.emplace_back(std::make_pair(PandaString("DateStyle"), GetDateStyle())); + vec.emplace_back(std::make_pair(PandaString("TimeStyle"), GetTimeStyle())); + vec.emplace_back(std::make_pair(PandaString("BoundFormat"), GetBoundFormat())); JSObject::DumpForSnapshot(thread, vec); } -void JSRelativeTimeFormat::DumpForSnapshot(JSThread *thread, std::vector> &vec) const +void JSRelativeTimeFormat::DumpForSnapshot(JSThread *thread, + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("Locale"), GetLocale())); - vec.emplace_back(std::make_pair(CString("InitializedRelativeTimeFormat"), GetInitializedRelativeTimeFormat())); - vec.emplace_back(std::make_pair(CString("NumberingSystem"), GetNumberingSystem())); - vec.emplace_back(std::make_pair(CString("Style"), GetStyle())); - vec.emplace_back(std::make_pair(CString("Numeric"), GetNumeric())); - vec.emplace_back(std::make_pair(CString("AvailableLocales"), GetAvailableLocales())); - vec.emplace_back(std::make_pair(CString("IcuField"), GetIcuField())); + vec.emplace_back(std::make_pair(PandaString("Locale"), GetLocale())); + vec.emplace_back(std::make_pair(PandaString("InitializedRelativeTimeFormat"), GetInitializedRelativeTimeFormat())); + vec.emplace_back(std::make_pair(PandaString("NumberingSystem"), GetNumberingSystem())); + vec.emplace_back(std::make_pair(PandaString("Style"), GetStyle())); + vec.emplace_back(std::make_pair(PandaString("Numeric"), GetNumeric())); + vec.emplace_back(std::make_pair(PandaString("AvailableLocales"), GetAvailableLocales())); + vec.emplace_back(std::make_pair(PandaString("IcuField"), GetIcuField())); JSObject::DumpForSnapshot(thread, vec); } -void JSNumberFormat::DumpForSnapshot(JSThread *thread, std::vector> &vec) const -{ - vec.emplace_back(std::make_pair(CString("Locale"), GetLocale())); - vec.emplace_back(std::make_pair(CString("NumberingSystem"), GetNumberingSystem())); - vec.emplace_back(std::make_pair(CString("Style"), GetStyle())); - vec.emplace_back(std::make_pair(CString("Currency"), GetCurrency())); - vec.emplace_back(std::make_pair(CString("CurrencyDisplay"), GetCurrencyDisplay())); - vec.emplace_back(std::make_pair(CString("CurrencySign"), GetCurrencySign())); - vec.emplace_back(std::make_pair(CString("Unit"), GetUnit())); - vec.emplace_back(std::make_pair(CString("UnitDisplay"), GetUnitDisplay())); - vec.emplace_back(std::make_pair(CString("MinimumIntegerDigits"), GetMinimumIntegerDigits())); - vec.emplace_back(std::make_pair(CString("MinimumFractionDigits"), GetMinimumFractionDigits())); - vec.emplace_back(std::make_pair(CString("MaximumFractionDigits"), GetMaximumFractionDigits())); - vec.emplace_back(std::make_pair(CString("MinimumSignificantDigits"), GetMinimumSignificantDigits())); - vec.emplace_back(std::make_pair(CString("MaximumSignificantDigits"), GetMaximumSignificantDigits())); - vec.emplace_back(std::make_pair(CString("UseGrouping"), GetUseGrouping())); - vec.emplace_back(std::make_pair(CString("RoundingType"), GetRoundingType())); - vec.emplace_back(std::make_pair(CString("Notation"), GetNotation())); - vec.emplace_back(std::make_pair(CString("CompactDisplay"), GetCompactDisplay())); - vec.emplace_back(std::make_pair(CString("SignDisplay"), GetSignDisplay())); - vec.emplace_back(std::make_pair(CString("BoundFormat"), GetBoundFormat())); - vec.emplace_back(std::make_pair(CString("IcuField"), GetIcuField())); +void JSNumberFormat::DumpForSnapshot(JSThread *thread, std::vector> &vec) const +{ + vec.emplace_back(std::make_pair(PandaString("Locale"), GetLocale())); + vec.emplace_back(std::make_pair(PandaString("NumberingSystem"), GetNumberingSystem())); + vec.emplace_back(std::make_pair(PandaString("Style"), GetStyle())); + vec.emplace_back(std::make_pair(PandaString("Currency"), GetCurrency())); + vec.emplace_back(std::make_pair(PandaString("CurrencyDisplay"), GetCurrencyDisplay())); + vec.emplace_back(std::make_pair(PandaString("CurrencySign"), GetCurrencySign())); + vec.emplace_back(std::make_pair(PandaString("Unit"), GetUnit())); + vec.emplace_back(std::make_pair(PandaString("UnitDisplay"), GetUnitDisplay())); + vec.emplace_back(std::make_pair(PandaString("MinimumIntegerDigits"), GetMinimumIntegerDigits())); + vec.emplace_back(std::make_pair(PandaString("MinimumFractionDigits"), GetMinimumFractionDigits())); + vec.emplace_back(std::make_pair(PandaString("MaximumFractionDigits"), GetMaximumFractionDigits())); + vec.emplace_back(std::make_pair(PandaString("MinimumSignificantDigits"), GetMinimumSignificantDigits())); + vec.emplace_back(std::make_pair(PandaString("MaximumSignificantDigits"), GetMaximumSignificantDigits())); + vec.emplace_back(std::make_pair(PandaString("UseGrouping"), GetUseGrouping())); + vec.emplace_back(std::make_pair(PandaString("RoundingType"), GetRoundingType())); + vec.emplace_back(std::make_pair(PandaString("Notation"), GetNotation())); + vec.emplace_back(std::make_pair(PandaString("CompactDisplay"), GetCompactDisplay())); + vec.emplace_back(std::make_pair(PandaString("SignDisplay"), GetSignDisplay())); + vec.emplace_back(std::make_pair(PandaString("BoundFormat"), GetBoundFormat())); + vec.emplace_back(std::make_pair(PandaString("IcuField"), GetIcuField())); JSObject::DumpForSnapshot(thread, vec); } -void JSCollator::DumpForSnapshot(JSThread *thread, std::vector> &vec) const +void JSCollator::DumpForSnapshot(JSThread *thread, std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("IcuField"), GetIcuField())); - vec.emplace_back(std::make_pair(CString("Locale"), GetLocale())); - vec.emplace_back(std::make_pair(CString("Usage"), GetUsage())); - vec.emplace_back(std::make_pair(CString("Sensitivity"), GetSensitivity())); - vec.emplace_back(std::make_pair(CString("IgnorePunctuation"), GetIgnorePunctuation())); - vec.emplace_back(std::make_pair(CString("Collation"), GetCollation())); - vec.emplace_back(std::make_pair(CString("Numeric"), GetNumeric())); - vec.emplace_back(std::make_pair(CString("CaseFirst"), GetCaseFirst())); - vec.emplace_back(std::make_pair(CString("BoundCompare"), GetBoundCompare())); + vec.emplace_back(std::make_pair(PandaString("IcuField"), GetIcuField())); + vec.emplace_back(std::make_pair(PandaString("Locale"), GetLocale())); + vec.emplace_back(std::make_pair(PandaString("Usage"), GetUsage())); + vec.emplace_back(std::make_pair(PandaString("Sensitivity"), GetSensitivity())); + vec.emplace_back(std::make_pair(PandaString("IgnorePunctuation"), GetIgnorePunctuation())); + vec.emplace_back(std::make_pair(PandaString("Collation"), GetCollation())); + vec.emplace_back(std::make_pair(PandaString("Numeric"), GetNumeric())); + vec.emplace_back(std::make_pair(PandaString("CaseFirst"), GetCaseFirst())); + vec.emplace_back(std::make_pair(PandaString("BoundCompare"), GetBoundCompare())); JSObject::DumpForSnapshot(thread, vec); } -void JSPluralRules::DumpForSnapshot(JSThread *thread, std::vector> &vec) const +void JSPluralRules::DumpForSnapshot(JSThread *thread, std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("Locale"), GetLocale())); - vec.emplace_back(std::make_pair(CString("InitializedPluralRules"), GetInitializedPluralRules())); - vec.emplace_back(std::make_pair(CString("Type"), GetType())); - vec.emplace_back(std::make_pair(CString("MinimumIntegerDigits"), GetMinimumIntegerDigits())); - vec.emplace_back(std::make_pair(CString("MinimumFractionDigits"), GetMinimumFractionDigits())); - vec.emplace_back(std::make_pair(CString("MaximumFractionDigits"), GetMaximumFractionDigits())); - vec.emplace_back(std::make_pair(CString("MinimumSignificantDigits"), GetMinimumSignificantDigits())); - vec.emplace_back(std::make_pair(CString("MaximumSignificantDigits"), GetMaximumSignificantDigits())); - vec.emplace_back(std::make_pair(CString("RoundingType"), GetRoundingType())); - vec.emplace_back(std::make_pair(CString("IcuPR"), GetIcuPR())); - vec.emplace_back(std::make_pair(CString("IcuNF"), GetIcuNF())); + vec.emplace_back(std::make_pair(PandaString("Locale"), GetLocale())); + vec.emplace_back(std::make_pair(PandaString("InitializedPluralRules"), GetInitializedPluralRules())); + vec.emplace_back(std::make_pair(PandaString("Type"), GetType())); + vec.emplace_back(std::make_pair(PandaString("MinimumIntegerDigits"), GetMinimumIntegerDigits())); + vec.emplace_back(std::make_pair(PandaString("MinimumFractionDigits"), GetMinimumFractionDigits())); + vec.emplace_back(std::make_pair(PandaString("MaximumFractionDigits"), GetMaximumFractionDigits())); + vec.emplace_back(std::make_pair(PandaString("MinimumSignificantDigits"), GetMinimumSignificantDigits())); + vec.emplace_back(std::make_pair(PandaString("MaximumSignificantDigits"), GetMaximumSignificantDigits())); + vec.emplace_back(std::make_pair(PandaString("RoundingType"), GetRoundingType())); + vec.emplace_back(std::make_pair(PandaString("IcuPR"), GetIcuPR())); + vec.emplace_back(std::make_pair(PandaString("IcuNF"), GetIcuNF())); JSObject::DumpForSnapshot(thread, vec); } -void JSGeneratorObject::DumpForSnapshot(JSThread *thread, std::vector> &vec) const +void JSGeneratorObject::DumpForSnapshot(JSThread *thread, std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("GeneratorState"), GetGeneratorState())); - vec.emplace_back(std::make_pair(CString("GeneratorContext"), GetGeneratorContext())); - vec.emplace_back(std::make_pair(CString("ResumeResult"), GetResumeResult())); - vec.emplace_back(std::make_pair(CString("ResumeMode"), GetResumeMode())); + vec.emplace_back(std::make_pair(PandaString("GeneratorState"), GetGeneratorState())); + vec.emplace_back(std::make_pair(PandaString("GeneratorContext"), GetGeneratorContext())); + vec.emplace_back(std::make_pair(PandaString("ResumeResult"), GetResumeResult())); + vec.emplace_back(std::make_pair(PandaString("ResumeMode"), GetResumeMode())); JSObject::DumpForSnapshot(thread, vec); } void JSAsyncGeneratorFunction::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { JSFunction::DumpForSnapshot(thread, vec); } void JSAsyncFuncObject::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("Promise"), GetPromise())); + vec.emplace_back(std::make_pair(PandaString("Promise"), GetPromise())); } void GeneratorContext::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("RegsArray"), GetRegsArray())); - vec.emplace_back(std::make_pair(CString("Method"), GetMethod())); - vec.emplace_back(std::make_pair(CString("Acc"), GetAcc())); - vec.emplace_back(std::make_pair(CString("NRegs"), GetNRegs())); - vec.emplace_back(std::make_pair(CString("BCOffset"), GetBCOffset())); - vec.emplace_back(std::make_pair(CString("GeneratorObject"), GetGeneratorObject())); - vec.emplace_back(std::make_pair(CString("LexicalEnv"), GetLexicalEnv())); + vec.emplace_back(std::make_pair(PandaString("RegsArray"), GetRegsArray())); + vec.emplace_back(std::make_pair(PandaString("Method"), GetMethod())); + vec.emplace_back(std::make_pair(PandaString("Acc"), GetAcc())); + vec.emplace_back(std::make_pair(PandaString("NRegs"), GetNRegs())); + vec.emplace_back(std::make_pair(PandaString("BCOffset"), GetBCOffset())); + vec.emplace_back(std::make_pair(PandaString("GeneratorObject"), GetGeneratorObject())); + vec.emplace_back(std::make_pair(PandaString("LexicalEnv"), GetLexicalEnv())); } void ProtoChangeMarker::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("Promise"), JSTaggedValue(GetHasChanged()))); + vec.emplace_back(std::make_pair(PandaString("Promise"), JSTaggedValue(GetHasChanged()))); } void ProtoChangeDetails::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("ChangeListener"), GetChangeListener())); - vec.emplace_back(std::make_pair(CString("RegisterIndex"), GetRegisterIndex())); + vec.emplace_back(std::make_pair(PandaString("ChangeListener"), GetChangeListener())); + vec.emplace_back(std::make_pair(PandaString("RegisterIndex"), GetRegisterIndex())); } void LexicalFunction::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("Name"), GetName())); - vec.emplace_back(std::make_pair(CString("NumberVRegs"), GetNumberVRegs())); - vec.emplace_back(std::make_pair(CString("NumberICSlots"), GetNumberICSlots())); - vec.emplace_back(std::make_pair(CString("Bytecode"), GetBytecode())); - vec.emplace_back(std::make_pair(CString("Program"), GetProgram())); + vec.emplace_back(std::make_pair(PandaString("Name"), GetName())); + vec.emplace_back(std::make_pair(PandaString("NumberVRegs"), GetNumberVRegs())); + vec.emplace_back(std::make_pair(PandaString("NumberICSlots"), GetNumberICSlots())); + vec.emplace_back(std::make_pair(PandaString("Bytecode"), GetBytecode())); + vec.emplace_back(std::make_pair(PandaString("Program"), GetProgram())); } void JSFunctionExtraInfo::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("Callback"), GetCallback())); - vec.emplace_back(std::make_pair(CString("Data"), GetData())); + vec.emplace_back(std::make_pair(PandaString("Callback"), GetCallback())); + vec.emplace_back(std::make_pair(PandaString("Data"), GetData())); } void MachineCode::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("InstructionSizeInBytes"), GetInstructionSizeInBytes())); + vec.emplace_back(std::make_pair(PandaString("InstructionSizeInBytes"), GetInstructionSizeInBytes())); } void EcmaModule::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const + std::vector> &vec) const { - vec.emplace_back(std::make_pair(CString("NameDictionary"), GetNameDictionary())); + vec.emplace_back(std::make_pair(PandaString("NameDictionary"), GetNameDictionary())); } void ClassInfoExtractor::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const -{ - vec.emplace_back(std::make_pair(CString("PrototypeHClass"), GetPrototypeHClass())); - vec.emplace_back(std::make_pair(CString("NonStaticKeys"), GetNonStaticKeys())); - vec.emplace_back(std::make_pair(CString("NonStaticProperties"), GetNonStaticProperties())); - vec.emplace_back(std::make_pair(CString("NonStaticElements"), GetNonStaticElements())); - vec.emplace_back(std::make_pair(CString("ConstructorHClass"), GetConstructorHClass())); - vec.emplace_back(std::make_pair(CString("StaticKeys"), GetStaticKeys())); - vec.emplace_back(std::make_pair(CString("StaticProperties"), GetStaticProperties())); - vec.emplace_back(std::make_pair(CString("StaticElements"), GetStaticElements())); + std::vector> &vec) const +{ + vec.emplace_back(std::make_pair(PandaString("PrototypeHClass"), GetPrototypeHClass())); + vec.emplace_back(std::make_pair(PandaString("NonStaticKeys"), GetNonStaticKeys())); + vec.emplace_back(std::make_pair(PandaString("NonStaticProperties"), GetNonStaticProperties())); + vec.emplace_back(std::make_pair(PandaString("NonStaticElements"), GetNonStaticElements())); + vec.emplace_back(std::make_pair(PandaString("ConstructorHClass"), GetConstructorHClass())); + vec.emplace_back(std::make_pair(PandaString("StaticKeys"), GetStaticKeys())); + vec.emplace_back(std::make_pair(PandaString("StaticProperties"), GetStaticProperties())); + vec.emplace_back(std::make_pair(PandaString("StaticElements"), GetStaticElements())); } } // namespace panda::ecmascript diff --git a/runtime/ecma_class_linker_extension.cpp b/runtime/ecma_class_linker_extension.cpp index a3c021210f0313822c78292ed344e7891255a007..745431ed81f9555eb9c1d82f77e0f0ac9c6f66e0 100644 --- a/runtime/ecma_class_linker_extension.cpp +++ b/runtime/ecma_class_linker_extension.cpp @@ -14,6 +14,7 @@ */ #include "plugins/ecmascript/runtime/ecma_class_linker_extension.h" +#include "plugins/ecmascript/runtime/js_tagged_value-inl.h" #include "plugins/ecmascript/runtime/mem/mem_manager-inl.h" #include "plugins/ecmascript/runtime/ecma_string.h" #include "plugins/ecmascript/runtime/object_factory.h" diff --git a/runtime/ecma_global_storage-inl.h b/runtime/ecma_global_storage-inl.h index 258aa3b6b776b0efa9771dc41640a2233677df2a..695c6f64dff39e7407e2cdb02f76d3ea03e82137 100644 --- a/runtime/ecma_global_storage-inl.h +++ b/runtime/ecma_global_storage-inl.h @@ -16,7 +16,6 @@ #define ECMASCRIPT_ECMA_GLOABL_STORAGE_INL_H #include "plugins/ecmascript/runtime/ecma_global_storage.h" -#include "plugins/ecmascript/runtime/mem/chunk.h" namespace panda::ecmascript { inline EcmaGlobalStorage::NodeList *EcmaGlobalStorage::NodeList::NodeToNodeList(EcmaGlobalStorage::Node *node) @@ -110,10 +109,11 @@ void EcmaGlobalStorage::NodeList::RemoveList() uintptr_t EcmaGlobalStorage::NewGlobalHandleImplement(NodeList **storage, NodeList **freeList, bool isWeak, JSTaggedType value) { + auto allocator = Runtime::GetCurrent()->GetInternalAllocator(); if (*freeList == nullptr) { if ((*storage)->IsFull()) { // alloc new block - auto block = chunk_->New(isWeak); + auto block = allocator->New(isWeak); block->LinkTo(*storage); *storage = block; } @@ -150,6 +150,7 @@ inline uintptr_t EcmaGlobalStorage::NewGlobalHandle(JSTaggedType value) inline void EcmaGlobalStorage::DisposeGlobalHandle(uintptr_t nodeAddr) { + auto allocator = Runtime::GetCurrent()->GetInternalAllocator(); Node *node = reinterpret_cast(nodeAddr); if (node->IsFree()) { return; @@ -181,7 +182,7 @@ inline void EcmaGlobalStorage::DisposeGlobalHandle(uintptr_t nodeAddr) if (*last == list) { *last = list->GetPrev(); } - chunk_->Delete(list); + allocator->Delete(list); } else { // Add to freeList if (list != *freeList && list->GetFreeNext() == nullptr && list->GetFreePrev() == nullptr) { diff --git a/runtime/ecma_global_storage.h b/runtime/ecma_global_storage.h index 46c9354a099c63e3026cc3e6d50a5b8df4d00357..5cf95918e910eea09a2b17cbe0b4880d9916839a 100644 --- a/runtime/ecma_global_storage.h +++ b/runtime/ecma_global_storage.h @@ -17,37 +17,36 @@ #define ECMASCRIPT_ECMA_GLOABL_STORAGE_H #include "plugins/ecmascript/runtime/js_tagged_value.h" - -#include "plugins/ecmascript/runtime/mem/c_containers.h" -#include "plugins/ecmascript/runtime/mem/chunk.h" +#include "runtime/include/runtime.h" namespace panda::ecmascript { class EcmaGlobalStorage { public: static const int32_t GLOBAL_BLOCK_SIZE = 256; - explicit EcmaGlobalStorage(Chunk *chunk) : chunk_(chunk) + explicit EcmaGlobalStorage() { - ASSERT(chunk != nullptr); - topGlobalNodes_ = lastGlobalNodes_ = chunk_->New(false); - topWeakGlobalNodes_ = lastWeakGlobalNodes_ = chunk_->New(true); + auto allocator = Runtime::GetCurrent()->GetInternalAllocator(); + topGlobalNodes_ = lastGlobalNodes_ = allocator->New(false); + topWeakGlobalNodes_ = lastWeakGlobalNodes_ = allocator->New(true); } ~EcmaGlobalStorage() { + auto allocator = Runtime::GetCurrent()->GetInternalAllocator(); NodeList *next = topGlobalNodes_; NodeList *current = nullptr; while (next != nullptr) { current = next; next = current->GetNext(); - chunk_->Delete(current); + allocator->Delete(current); } next = topWeakGlobalNodes_; while (next != nullptr) { current = next; next = current->GetNext(); - chunk_->Delete(current); + allocator->Delete(current); } } @@ -256,7 +255,6 @@ private: inline uintptr_t NewGlobalHandleImplement(NodeList **storage, NodeList **freeList, bool isWeak, JSTaggedType value); - Chunk *chunk_ {nullptr}; NodeList *topGlobalNodes_ {nullptr}; NodeList *lastGlobalNodes_ {nullptr}; NodeList *freeListNodes_ {nullptr}; diff --git a/runtime/ecma_macros.h b/runtime/ecma_macros.h index a92a7b37fda5526a3094dc59ea0f3934ed1e4ac6..792c52e4fb49e5e4bea012668db8ac2472ef8243 100644 --- a/runtime/ecma_macros.h +++ b/runtime/ecma_macros.h @@ -21,7 +21,6 @@ #include "plugins/ecmascript/runtime/js_tagged_value.h" #include "plugins/ecmascript/runtime/js_thread.h" #include "plugins/ecmascript/runtime/mem/barriers-inl.h" -#include "plugins/ecmascript/runtime/mem/slots.h" #include "utils/logger.h" #if defined(__cplusplus) @@ -385,7 +384,7 @@ static inline void UnalignedStore(T *p, T v) { \ Dump(thread, std::cout); \ } \ - void DumpForSnapshot(JSThread *thread, std::vector> &vec) const; + void DumpForSnapshot(JSThread *thread, std::vector> &vec) const; #endif // defined(__cplusplus) diff --git a/runtime/ecma_module.cpp b/runtime/ecma_module.cpp index 96790105b7320f012983a9398b4673bd8d67b0f9..93f2369bad8d6673f478b2784e2d9de9a60c6168 100644 --- a/runtime/ecma_module.cpp +++ b/runtime/ecma_module.cpp @@ -83,7 +83,7 @@ void EcmaModule::CopyModuleInternal(const JSThread *thread, JSHandle } } -void EcmaModule::DebugPrint(const JSThread *thread, const CString &caller) +void EcmaModule::DebugPrint(const JSThread *thread, const PandaString &caller) { JSHandle moduleItems(thread, NameDictionary::Cast(GetNameDictionary().GetTaggedObject())); uint32_t numAllKeys = moduleItems->EntriesCount(); @@ -96,7 +96,7 @@ void EcmaModule::DebugPrint(const JSThread *thread, const CString &caller) int entry = moduleItems->FindEntry(allKeys->Get(i)); if (entry != -1) { std::cout << "[" << caller << "]" << std::endl - << "--itemName: " << ConvertToString(EcmaString::Cast(allKeys->Get(i).GetTaggedObject())) + << "--itemName: " << ConvertToPandaString(EcmaString::Cast(allKeys->Get(i).GetTaggedObject())) << std::endl << "--itemValue(ObjRef): 0x" << std::hex << moduleItems->GetValue(entry).GetRawData() << std::endl; @@ -140,7 +140,7 @@ JSHandle ModuleManager::GetModule(const JSThread *thread, return thread->GlobalConstants()->GetHandledUndefined(); } -CString ModuleManager::GenerateModuleFullPath(const std::string ¤tPathFile, const CString &relativeFile) +PandaString ModuleManager::GenerateModuleFullPath(const std::string ¤tPathFile, const PandaString &relativeFile) { // NOLINTNEXTLINE(abseil-string-find-startswith) if (relativeFile.find("./") != 0 && relativeFile.find("../") != 0) { // not start with "./" or "../" @@ -157,21 +157,21 @@ CString ModuleManager::GenerateModuleFullPath(const std::string ¤tPathFile dotPos = 0; } - CString fullPath; + PandaString fullPath; fullPath.append(currentPathFile.substr(0, slashPos + 1)); // 1: with "/" fullPath.append(relativeFile.substr(0, dotPos)); fullPath.append(".abc"); // ".js" -> ".abc" return fullPath; } -const CString &ModuleManager::GetCurrentExportModuleName() +const PandaString &ModuleManager::GetCurrentExportModuleName() { return moduleNames_.back(); } void ModuleManager::SetCurrentExportModuleName(const std::string_view &moduleFile) { - moduleNames_.emplace_back(CString(moduleFile)); // xx/xx/x.abc + moduleNames_.emplace_back(PandaString(moduleFile)); // xx/xx/x.abc } void ModuleManager::RestoreCurrentExportModuleName() @@ -184,7 +184,7 @@ void ModuleManager::RestoreCurrentExportModuleName() UNREACHABLE(); } -const CString &ModuleManager::GetPrevExportModuleName() +const PandaString &ModuleManager::GetPrevExportModuleName() { static const int MINIMUM_COUNT = 2; auto count = moduleNames_.size(); @@ -195,7 +195,7 @@ const CString &ModuleManager::GetPrevExportModuleName() void ModuleManager::AddModuleItem(const JSThread *thread, JSHandle itemName, JSHandle value) { - CString name_str = GetCurrentExportModuleName(); + PandaString name_str = GetCurrentExportModuleName(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle moduleName = factory->NewFromString(name_str); @@ -221,7 +221,7 @@ void ModuleManager::CopyModule(const JSThread *thread, JSHandle s { ASSERT(src->IsHeapObject()); JSHandle srcModule = JSHandle::Cast(src); - CString name_str = GetCurrentExportModuleName(); // Assume the srcModule exist when dstModule Execute + PandaString name_str = GetCurrentExportModuleName(); // Assume the srcModule exist when dstModule Execute ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle moduleName = factory->NewFromString(name_str); @@ -238,10 +238,10 @@ void ModuleManager::CopyModule(const JSThread *thread, JSHandle s } } -void ModuleManager::DebugPrint([[maybe_unused]] const JSThread *thread, [[maybe_unused]] const CString &caller) +void ModuleManager::DebugPrint([[maybe_unused]] const JSThread *thread, [[maybe_unused]] const PandaString &caller) { std::cout << "ModuleStack:"; - for_each(moduleNames_.cbegin(), moduleNames_.cend(), [](const CString &s) -> void { std::cout << s << " "; }); + for_each(moduleNames_.cbegin(), moduleNames_.cend(), [](const PandaString &s) -> void { std::cout << s << " "; }); std::cout << "\n"; } } // namespace panda::ecmascript diff --git a/runtime/ecma_module.h b/runtime/ecma_module.h index 440181eeca125486b6c2c19ab8b12bedeb7f2f0c..83143cecbbda4c050a9583b4612bd1db53e371d1 100644 --- a/runtime/ecma_module.h +++ b/runtime/ecma_module.h @@ -18,7 +18,7 @@ #include "plugins/ecmascript/runtime/js_object.h" #include "plugins/ecmascript/runtime/js_tagged_value-inl.h" -#include "plugins/ecmascript/runtime/mem/c_string.h" +#include "plugins/ecmascript/runtime/mem/ecma_string.h" namespace panda::ecmascript { class EcmaVm; @@ -38,7 +38,7 @@ public: static void RemoveItem(const JSThread *thread, JSHandle module, JSHandle itemName); - void DebugPrint(const JSThread *thread, const CString &caller); + void DebugPrint(const JSThread *thread, const PandaString &caller); static constexpr uint32_t DEAULT_DICTIONART_CAPACITY = 4; @@ -66,11 +66,11 @@ public: JSHandle GetModule(const JSThread *thread, JSHandle moduleName); - CString GenerateModuleFullPath(const std::string ¤tPathFile, const CString &relativeFile); + PandaString GenerateModuleFullPath(const std::string ¤tPathFile, const PandaString &relativeFile); - const CString &GetCurrentExportModuleName(); + const PandaString &GetCurrentExportModuleName(); - const CString &GetPrevExportModuleName(); + const PandaString &GetPrevExportModuleName(); void SetCurrentExportModuleName(const std::string_view &moduleFile); @@ -83,7 +83,7 @@ public: void CopyModule(const JSThread *thread, JSHandle src); - void DebugPrint(const JSThread *thread, const CString &caller); + void DebugPrint(const JSThread *thread, const PandaString &caller); private: static constexpr uint32_t DEAULT_DICTIONART_CAPACITY = 4; @@ -93,7 +93,7 @@ private: EcmaVM *vm_ {nullptr}; JSTaggedValue ecmaModules_ {JSTaggedValue::Hole()}; - std::vector moduleNames_ {DEAULT_DICTIONART_CAPACITY}; + std::vector moduleNames_ {DEAULT_DICTIONART_CAPACITY}; friend class EcmaVM; }; diff --git a/runtime/ecma_string.cpp b/runtime/ecma_string.cpp index 0f462774f9db6eb63770bc2b50faa4f034d5676a..8b6d085c3b5d36c84a27ff253cd544ca3146a78c 100644 --- a/runtime/ecma_string.cpp +++ b/runtime/ecma_string.cpp @@ -16,7 +16,6 @@ #include "plugins/ecmascript/runtime/ecma_string-inl.h" #include "plugins/ecmascript/runtime/js_symbol.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" namespace panda::ecmascript { bool EcmaString::compressedStringsEnabled = true; @@ -413,7 +412,7 @@ uint32_t EcmaString::ComputeHashcodeUtf8(const uint8_t *utf8Data, size_t utf8Len hash = ComputeHashForUtf8(utf8Data); } else { auto utf16Len = base::utf_helper::Utf8ToUtf16Size(utf8Data, utf8Len); - CVector tmpBuffer(utf16Len); + PandaVector tmpBuffer(utf16Len); [[maybe_unused]] auto len = base::utf_helper::ConvertRegionUtf8ToUtf16(utf8Data, tmpBuffer.data(), utf8Len, utf16Len, 0); ASSERT(len == utf16Len); @@ -434,7 +433,7 @@ bool EcmaString::IsUtf8EqualsUtf16(const uint8_t *utf8Data, size_t utf8Len, cons { // length is one more than compared utf16Data, don't need convert all utf8Data to utf16Data uint32_t utf8ConvertLength = utf16Len + 1; - CVector tmpBuffer(utf8ConvertLength); + PandaVector tmpBuffer(utf8ConvertLength); auto len = base::utf_helper::ConvertRegionUtf8ToUtf16(utf8Data, tmpBuffer.data(), utf8Len, utf8ConvertLength, 0); if (len != utf16Len) { return false; diff --git a/runtime/ecma_string_table.cpp b/runtime/ecma_string_table.cpp index 27d948f016783a1d2537079170a446179f0dddfc..6b754c34073cf59943cc598ebba831bfb1b08495 100644 --- a/runtime/ecma_string_table.cpp +++ b/runtime/ecma_string_table.cpp @@ -18,7 +18,7 @@ #include "plugins/ecmascript/runtime/ecma_string-inl.h" #include "plugins/ecmascript/runtime/ecma_vm.h" #include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/c_string.h" +#include "plugins/ecmascript/runtime/mem/ecma_string.h" #include "plugins/ecmascript/runtime/object_factory.h" namespace panda::ecmascript { @@ -150,7 +150,7 @@ void EcmaStringTable::Sweep(const GCObjectVisitor &visitor) LOG(DEBUG, GC) << "StringTable: forward " << std::hex << object << " -> " << fwd_string; } else if (visitor(object) == ObjectStatus::DEAD_OBJECT) { LOG(DEBUG, GC) << "StringTable: delete string " << std::hex << object - << ", val = " << ConvertToString(object); + << ", val = " << ConvertToPandaString(object); table_.erase(it++); } else { ++it; @@ -183,7 +183,7 @@ void EcmaStringTable::SweepWeakReference(const WeakRootVisitor &visitor) auto fwd = visitor(object); if (fwd == nullptr) { LOG(DEBUG, GC) << "StringTable: delete string " << std::hex << object - << ", val = " << ConvertToString(object); + << ", val = " << ConvertToPandaString(object); table_.erase(it++); } else if (fwd != object) { it->second = static_cast(fwd); diff --git a/runtime/ecma_string_table.h b/runtime/ecma_string_table.h index a60977a8727242d70d9a399ea01c69e27f40aafd..335c22f421206be18dd61cf857908bb5c45357d6 100644 --- a/runtime/ecma_string_table.h +++ b/runtime/ecma_string_table.h @@ -16,7 +16,6 @@ #ifndef ECMASCRIPT_STRING_TABLE_H #define ECMASCRIPT_STRING_TABLE_H -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "plugins/ecmascript/runtime/mem/object_xray.h" #include "runtime/string_table.h" @@ -67,10 +66,9 @@ private: } } - CUnorderedMultiMap table_ GUARDED_BY(table_lock_); + PandaUnorderedMultiMap table_ GUARDED_BY(table_lock_); mutable os::memory::RWLock table_lock_; const EcmaVM *vm_ {nullptr}; - friend class SnapShotSerialize; }; } // namespace panda::ecmascript diff --git a/runtime/ecma_vm.cpp b/runtime/ecma_vm.cpp index bab1724126f4abad5748d6defcaa9d790af5c827..a3156c29a33d7f3b969b3539d51f6fc868f906c9 100644 --- a/runtime/ecma_vm.cpp +++ b/runtime/ecma_vm.cpp @@ -17,7 +17,6 @@ #include "plugins/ecmascript/runtime/bridge.h" #include "js_tagged_value.h" -#include "mem/mark_word.h" #include "plugins/ecmascript/runtime/base/string_helper.h" #include "plugins/ecmascript/runtime/builtins.h" #include "plugins/ecmascript/runtime/builtins/builtins_regexp.h" @@ -37,16 +36,10 @@ #include "plugins/ecmascript/runtime/js_invoker.h" #include "plugins/ecmascript/runtime/js_native_pointer.h" #include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/concurrent_marker.h" -#include "plugins/ecmascript/runtime/mem/heap.h" #include "plugins/ecmascript/runtime/mem/object_xray-inl.h" #include "plugins/ecmascript/runtime/object_factory.h" -#include "plugins/ecmascript/runtime/platform/platform.h" #include "plugins/ecmascript/runtime/regexp/regexp_parser_cache.h" #include "plugins/ecmascript/runtime/runtime_call_id.h" -#include "plugins/ecmascript/runtime/snapshot/mem/slot_bit.h" -#include "plugins/ecmascript/runtime/snapshot/mem/snapshot.h" -#include "plugins/ecmascript/runtime/snapshot/mem/snapshot_serialize.h" #include "plugins/ecmascript/runtime/symbol_table.h" #include "plugins/ecmascript/runtime/tagged_array-inl.h" #include "plugins/ecmascript/runtime/tagged_dictionary.h" @@ -169,7 +162,7 @@ bool EcmaVM::Destroy(PandaVM *vm) } // static -Expected EcmaVM::Create(Runtime *runtime, const JSRuntimeOptions &options) +Expected EcmaVM::Create(Runtime *runtime, const JSRuntimeOptions &options) { EcmaVM *vm = runtime->GetInternalAllocator()->New(options); if (UNLIKELY(vm == nullptr)) { @@ -182,25 +175,17 @@ Expected EcmaVM::Create(Runtime *runtime, const JSRuntimeOpti return vm; } -EcmaVM::EcmaVM(JSRuntimeOptions options) - : stringTable_(new EcmaStringTable(this)), - regionFactory_(std::make_unique()), - chunk_(regionFactory_.get()), - nativeMethods_(&chunk_) +EcmaVM::EcmaVM(JSRuntimeOptions options) : stringTable_(new EcmaStringTable(this)) { + auto runtime = Runtime::GetCurrent(); options_ = std::move(options); icEnable_ = options_.IsIcEnable(); optionalLogEnabled_ = options_.IsEnableOptionalLog(); - rendezvous_ = chunk_.New(this); - snapshotSerializeEnable_ = options_.IsSnapshotSerializeEnabled(); - if (!snapshotSerializeEnable_) { - snapshotDeserializeEnable_ = options_.IsSnapshotDeserializeEnabled(); - } - snapshotFileName_ = options_.GetSnapshotFile(); + rendezvous_ = runtime->GetInternalAllocator()->New(this); frameworkAbcFileName_ = options_.GetFrameworkAbcFile(); - auto runtime = Runtime::GetCurrent(); - notificationManager_ = chunk_.New(runtime->GetInternalAllocator()); + auto allocator = runtime->GetInternalAllocator(); + notificationManager_ = allocator->New(runtime->GetInternalAllocator()); notificationManager_->SetRendezvous(rendezvous_); LanguageContext ctx = Runtime::GetCurrent()->GetLanguageContext(panda_file::SourceLang::ECMASCRIPT); @@ -242,20 +227,16 @@ void EcmaVM::LoadEcmaStdLib() bool EcmaVM::Initialize() { ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "EcmaVM::Initialize"); - Platform::GetCurrentPlatform()->Initialize(); + auto runtime = Runtime::GetCurrent(); auto globalConst = const_cast(thread_->GlobalConstants()); regExpParserCache_ = new RegExpParserCache(); - heap_ = new Heap(this); - heap_->Initialize(); - gcStats_ = chunk_.New(heap_); - factory_ = chunk_.New(thread_, heap_); + factory_ = runtime->GetInternalAllocator()->New(thread_); if (UNLIKELY(factory_ == nullptr)) { LOG_ECMA(FATAL) << "alloc factory_ failed"; UNREACHABLE(); } - auto runtime = Runtime::GetCurrent(); LanguageContext ctx = runtime->GetLanguageContext(panda_file::SourceLang::ECMASCRIPT); EcmaClassLinkerExtension::Cast(runtime->GetClassLinker()->GetExtension(ctx))->InitClasses(this); @@ -266,82 +247,50 @@ bool EcmaVM::Initialize() } [[maybe_unused]] EcmaHandleScope scope(thread_); - if (!snapshotDeserializeEnable_ || !VerifyFilePath(snapshotFileName_)) { - LOG_ECMA(DEBUG) << "EcmaVM::Initialize run builtins"; - - JSHandle dynClassClassHandle = - factory_->NewEcmaDynClassClass(nullptr, JSHClass::SIZE, JSType::HCLASS); - JSHClass *dynclass = reinterpret_cast(dynClassClassHandle.GetTaggedValue().GetTaggedObject()); - dynclass->SetClass(dynclass); - JSHandle globalEnvClass = - factory_->NewEcmaDynClass(*dynClassClassHandle, GlobalEnv::SIZE, JSType::GLOBAL_ENV); - - JSHandle globalEnvHandle = factory_->NewGlobalEnv(*globalEnvClass); - globalEnv_ = globalEnvHandle.GetTaggedValue(); - - // init global env - globalConst->InitRootsClass(thread_, *dynClassClassHandle); - factory_->ObtainRootClass(GetGlobalEnv()); - globalConst->InitGlobalConstant(thread_); - globalEnvHandle->SetEmptyArray(thread_, factory_->NewEmptyArray()); - globalEnvHandle->SetEmptyWeakArray(thread_, factory_->NewEmptyArray(true)); - globalEnvHandle->SetEmptyLayoutInfo(thread_, factory_->CreateLayoutInfo(0)); - globalEnvHandle->SetRegisterSymbols(thread_, SymbolTable::Create(thread_)); - globalEnvHandle->SetGlobalRecord(thread_, GlobalDictionary::Create(thread_)); - JSTaggedValue emptyStr = thread_->GlobalConstants()->GetEmptyString(); - stringTable_->InternEmptyString(EcmaString::Cast(emptyStr.GetTaggedObject())); - globalEnvHandle->SetEmptyTaggedQueue(thread_, factory_->NewTaggedQueue(0)); - globalEnvHandle->SetTemplateMap(thread_, TemplateMap::Create(thread_)); - globalEnvHandle->SetRegisterSymbols(GetJSThread(), SymbolTable::Create(GetJSThread())); + LOG_ECMA(DEBUG) << "EcmaVM::Initialize run builtins"; + + JSHandle dynClassClassHandle = factory_->NewEcmaDynClassClass(nullptr, JSHClass::SIZE, JSType::HCLASS); + JSHClass *dynclass = reinterpret_cast(dynClassClassHandle.GetTaggedValue().GetTaggedObject()); + dynclass->SetClass(dynclass); + JSHandle globalEnvClass = + factory_->NewEcmaDynClass(*dynClassClassHandle, GlobalEnv::SIZE, JSType::GLOBAL_ENV); + + JSHandle globalEnvHandle = factory_->NewGlobalEnv(*globalEnvClass); + globalEnv_ = globalEnvHandle.GetTaggedValue(); + + // init global env + globalConst->InitRootsClass(thread_, *dynClassClassHandle); + factory_->ObtainRootClass(GetGlobalEnv()); + globalConst->InitGlobalConstant(thread_); + globalEnvHandle->SetEmptyArray(thread_, factory_->NewEmptyArray()); + globalEnvHandle->SetEmptyWeakArray(thread_, factory_->NewEmptyArray(true)); + globalEnvHandle->SetEmptyLayoutInfo(thread_, factory_->CreateLayoutInfo(0)); + globalEnvHandle->SetRegisterSymbols(thread_, SymbolTable::Create(thread_)); + globalEnvHandle->SetGlobalRecord(thread_, GlobalDictionary::Create(thread_)); + JSTaggedValue emptyStr = thread_->GlobalConstants()->GetEmptyString(); + stringTable_->InternEmptyString(EcmaString::Cast(emptyStr.GetTaggedObject())); + globalEnvHandle->SetEmptyTaggedQueue(thread_, factory_->NewTaggedQueue(0)); + globalEnvHandle->SetTemplateMap(thread_, TemplateMap::Create(thread_)); + globalEnvHandle->SetRegisterSymbols(GetJSThread(), SymbolTable::Create(GetJSThread())); #ifdef ECMASCRIPT_ENABLE_STUB_AOT - std::string moduleFile = options_.GetStubModuleFile(); - thread_->LoadFastStubModule(moduleFile.c_str()); + std::string moduleFile = options_.GetStubModuleFile(); + thread_->LoadFastStubModule(moduleFile.c_str()); #endif - SetupRegExpResultCache(); - microJobQueue_ = factory_->NewMicroJobQueue().GetTaggedValue(); + SetupRegExpResultCache(); + microJobQueue_ = factory_->NewMicroJobQueue().GetTaggedValue(); - { - Builtins builtins; - builtins.Initialize(globalEnvHandle, thread_); - } - - thread_->SetGlobalObject(globalEnvHandle->GetGlobalObject()); - } else { - LOG_ECMA(DEBUG) << "EcmaVM::Initialize run snapshot"; - SnapShot snapShot(this); - std::unique_ptr pf = snapShot.DeserializeGlobalEnvAndProgram(snapshotFileName_); - frameworkPandaFile_ = pf.get(); - AddPandaFile(pf.release(), false); - SetProgram(Program::Cast(frameworkProgram_.GetTaggedObject()), frameworkPandaFile_); - notificationManager_->LoadModuleEvent(pf->GetFilename()); - globalConst->InitGlobalUndefined(); - - factory_->ObtainRootClass(GetGlobalEnv()); + { + Builtins builtins; + builtins.Initialize(globalEnvHandle, thread_); } + thread_->SetGlobalObject(globalEnvHandle->GetGlobalObject()); + moduleManager_ = new ModuleManager(this); InitializeFinish(); notificationManager_->VmStartEvent(); notificationManager_->VmInitializationEvent(thread_->GetThreadId()); - Platform::GetCurrentPlatform()->PostTask(std::make_unique(heap_)); - return true; -} - -bool EcmaVM::TrimNewSpaceLimitTask::Run([[maybe_unused]] uint32_t threadIndex) -{ - for (uint32_t i = 0; i < THREAD_SLEEP_COUNT; i++) { - if (IsTerminate()) { - return false; - } - usleep(THREAD_SLEEP_TIME); - } - - if (!IsTerminate() && heap_->GetMemController()->IsDelayGCMode()) { - heap_->SetFromSpaceMaximumCapacity(SEMI_SPACE_SIZE_CAPACITY); - heap_->SetNewSpaceMaximumCapacity(SEMI_SPACE_SIZE_CAPACITY); - heap_->ResetDelayGCMode(); - } return true; } @@ -364,7 +313,8 @@ void EcmaVM::InitializeEcmaScriptRunStat() }; static_assert(sizeof(runtimeCallerNames) == sizeof(const char *) * ecmascript::RUNTIME_CALLER_NUMBER, "Invalid runtime caller number"); - runtimeStat_ = chunk_.New(runtimeCallerNames, ecmascript::RUNTIME_CALLER_NUMBER); + auto allocator = Runtime::GetCurrent()->GetInternalAllocator(); + runtimeStat_ = allocator->New(runtimeCallerNames, ecmascript::RUNTIME_CALLER_NUMBER); if (UNLIKELY(runtimeStat_ == nullptr)) { LOG_ECMA(FATAL) << "alloc runtimeStat_ failed"; UNREACHABLE(); @@ -401,7 +351,6 @@ void EcmaVM::UninitializeThreads() EcmaVM::~EcmaVM() { vmInitialized_ = false; - Platform::GetCurrentPlatform()->Destroy(); ClearNativeMethodsData(); if (panda::plugins::RuntimeTypeToLang(Runtime::GetCurrent()->GetRuntimeType()) != @@ -417,43 +366,14 @@ EcmaVM::~EcmaVM() // clear c_address: c++ pointer delete ClearBufferData(); - if (gcStats_ != nullptr) { - if (options_.IsEnableGCStatsPrint()) { - gcStats_->PrintStatisticResult(true); - } - chunk_.Delete(gcStats_); - gcStats_ = nullptr; - } - - if (heap_ != nullptr) { - heap_->Destroy(); - delete heap_; - heap_ = nullptr; - } - delete regExpParserCache_; regExpParserCache_ = nullptr; - if (notificationManager_ != nullptr) { - chunk_.Delete(notificationManager_); - notificationManager_ = nullptr; - } - - if (factory_ != nullptr) { - chunk_.Delete(factory_); - factory_ = nullptr; - } - if (stringTable_ != nullptr) { delete stringTable_; stringTable_ = nullptr; } - if (runtimeStat_ != nullptr) { - chunk_.Delete(runtimeStat_); - runtimeStat_ = nullptr; - } - if (moduleManager_ != nullptr) { delete moduleManager_; moduleManager_ = nullptr; @@ -469,6 +389,10 @@ EcmaVM::~EcmaVM() frameworkProgramMethods_.clear(); mem::InternalAllocatorPtr allocator = mm_->GetHeapManager()->GetInternalAllocator(); + allocator->Delete(notificationManager_); + allocator->Delete(factory_); + allocator->Delete(runtimeStat_); + allocator->Delete(rendezvous_); allocator->Delete(runtime_iface_); allocator->Delete(compiler_); @@ -536,7 +460,7 @@ bool EcmaVM::Execute(std::unique_ptr pf, std::string_vie LOG_ECMA(ERROR) << "EntryPoint:" << entryPoint << " is illegal"; return false; } - CString methodName(entryPoint.substr(pos + 1)); + PandaString methodName(entryPoint.substr(pos + 1)); // For Ark application startup if (!isModule) { @@ -607,7 +531,8 @@ JSMethod *EcmaVM::GetMethodForNativeFunction(const void *func) { Method *n_wrapper = GetNativeMethodWrapper(); ASSERT(n_wrapper != nullptr); - auto method = chunk_.New(n_wrapper); + auto allocator = Runtime::GetCurrent()->GetInternalAllocator(); + auto method = allocator->New(n_wrapper); method->SetNativePointer(const_cast(func)); method->SetCompiledEntryPoint(reinterpret_cast(CompiledCodeToBuiltinBridge)); @@ -636,30 +561,18 @@ Expected EcmaVM::InvokeEntrypointImpl(Method *entrypoint, c return InvokeEcmaEntrypoint(*file, utf::Mutf8AsCString(entrypoint->GetName().data), args); } -Expected EcmaVM::InvokeEcmaEntrypoint(const panda_file::File &pf, const CString &methodName, +Expected EcmaVM::InvokeEcmaEntrypoint(const panda_file::File &pf, const PandaString &methodName, const std::vector &args) { [[maybe_unused]] EcmaHandleScope scope(thread_); JSHandle program; - if (snapshotSerializeEnable_) { + if (&pf != frameworkPandaFile_) { program = PandaFileTranslator::TranslatePandaFile(this, pf, methodName); - auto string = EcmaString::Cast(program->GetLocation().GetTaggedObject()); - - auto index = ConvertToString(string).find(frameworkAbcFileName_); - if (index != CString::npos) { - LOG_ECMA(DEBUG) << "snapShot MakeSnapShotProgramObject abc " << ConvertToString(string); - SnapShot snapShot(this); - snapShot.MakeSnapShotProgramObject(*program, &pf, snapshotFileName_); - } } else { - if (&pf != frameworkPandaFile_) { - program = PandaFileTranslator::TranslatePandaFile(this, pf, methodName); - } else { - JSHandle string = factory_->NewFromStdStringUnCheck(pf.GetFilename(), true); - program = JSHandle(thread_, frameworkProgram_); - program->SetLocation(thread_, string); - RedirectMethod(pf); - } + JSHandle string = factory_->NewFromStdStringUnCheck(pf.GetFilename(), true); + program = JSHandle(thread_, frameworkProgram_); + program->SetLocation(thread_, string); + RedirectMethod(pf); } SetProgram(*program, &pf); @@ -753,7 +666,7 @@ void EcmaVM::HandleUncaughtException() PrintJSErrorInfo(throwValue); } else { JSHandle result = JSTaggedValue::ToString(thread_, throwValue); - CString string = ConvertToString(*result); + PandaString string = ConvertToPandaString(*result); LOG(ERROR, RUNTIME) << string; } } @@ -768,9 +681,9 @@ void EcmaVM::PrintJSErrorInfo(const JSHandle &exceptionInfo) JSHandle stackKey = thread_->GlobalConstants()->GetHandledStackString(); JSHandle stack(JSObject::GetProperty(thread_, exceptionInfo, stackKey).GetValue()); - CString nameBuffer = ConvertToString(*name); - CString msgBuffer = ConvertToString(*msg); - CString stackBuffer = ConvertToString(*stack); + PandaString nameBuffer = ConvertToPandaString(*name); + PandaString msgBuffer = ConvertToPandaString(*msg); + PandaString stackBuffer = ConvertToPandaString(*stack); LOG(ERROR, RUNTIME) << nameBuffer << ": " << msgBuffer << "\n" << stackBuffer; } @@ -863,13 +776,13 @@ void EcmaVM::RemoveArrayDataList(JSNativePointer *array) } } -bool EcmaVM::VerifyFilePath(const CString &filePath) const +bool EcmaVM::VerifyFilePath(const PandaString &filePath) const { if (filePath.size() > PATH_MAX) { return false; } - CVector resolvedPath(PATH_MAX); + PandaVector resolvedPath(PATH_MAX); auto result = realpath(filePath.c_str(), resolvedPath.data()); if (result == nullptr) { return false; @@ -906,21 +819,11 @@ bool EcmaVM::ExecutePromisePendingJob() const return false; } -void EcmaVM::CollectGarbage([[maybe_unused]] TriggerGCType gcType) const +void EcmaVM::CollectGarbage() const { mm_->GetGC()->WaitForGCInManaged(GCTask(GCTaskCause::EXPLICIT_CAUSE)); } -void EcmaVM::StartHeapTracking(HeapTracker *tracker) -{ - heap_->StartHeapTracking(tracker); -} - -void EcmaVM::StopHeapTracking() -{ - heap_->StopHeapTracking(); -} - void EcmaVM::Iterate(const RootVisitor &v) { v(Root::ROOT_VM, ObjectSlot(ToUintPtr(&globalEnv_))); @@ -951,17 +854,17 @@ const panda_file::File *EcmaVM::GetLastLoadedPandaFile() JSHandle EcmaVM::GetModuleByName(JSHandle moduleName) { const std::string ¤tPathFile = GetLastLoadedPandaFile()->GetFilename(); - CString relativeFile = ConvertToString(EcmaString::Cast(moduleName->GetTaggedObject())); + PandaString relativeFile = ConvertToPandaString(EcmaString::Cast(moduleName->GetTaggedObject())); // generate full path - CString abcPath = moduleManager_->GenerateModuleFullPath(currentPathFile, relativeFile); + PandaString abcPath = moduleManager_->GenerateModuleFullPath(currentPathFile, relativeFile); // Uniform module name JSHandle abcModuleName = factory_->NewFromString(abcPath); JSHandle module = moduleManager_->GetModule(thread_, JSHandle::Cast(abcModuleName)); if (module->IsUndefined()) { - CString file = ConvertToString(abcModuleName.GetObject()); + PandaString file = ConvertToPandaString(abcModuleName.GetObject()); std::vector argv; ExecuteModule(file, ENTRY_POINTER, argv); module = moduleManager_->GetModule(thread_, JSHandle::Cast(abcModuleName)); @@ -981,8 +884,9 @@ void EcmaVM::ExecuteModule(std::string_view moduleFile, std::string_view entryPo void EcmaVM::ClearNativeMethodsData() { + auto allocator = Runtime::GetCurrent()->GetInternalAllocator(); for (auto iter : nativeMethods_) { - chunk_.Delete(iter); + allocator->Delete(iter); } nativeMethods_.clear(); } diff --git a/runtime/ecma_vm.h b/runtime/ecma_vm.h index 0f46dfce117672e237758155bd34a386e26f37c4..4499509e321ccbc6e905d61f33037b4af78a73c9 100644 --- a/runtime/ecma_vm.h +++ b/runtime/ecma_vm.h @@ -18,21 +18,15 @@ #include +#include "include/mem/panda_containers.h" #include "plugins/ecmascript/runtime/base/config.h" #include "plugins/ecmascript/runtime/ecma_string_table.h" #include "plugins/ecmascript/runtime/global_handle_collection.h" #include "plugins/ecmascript/runtime/js_handle.h" #include "plugins/ecmascript/runtime/js_method.h" #include "plugins/ecmascript/runtime/js_runtime_options.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" -#include "plugins/ecmascript/runtime/mem/c_string.h" -#include "plugins/ecmascript/runtime/mem/chunk_containers.h" -#include "plugins/ecmascript/runtime/mem/gc_stats.h" -#include "plugins/ecmascript/runtime/platform/platform.h" +#include "plugins/ecmascript/runtime/mem/ecma_string.h" #include "plugins/ecmascript/runtime/mem/object_xray.h" -#include "plugins/ecmascript/runtime/mem/space.h" -#include "plugins/ecmascript/runtime/platform/task.h" -#include "plugins/ecmascript/runtime/snapshot/mem/snapshot_serialize.h" #include "plugins/ecmascript/runtime/tooling/pt_js_extractor.h" #include "include/panda_vm.h" #include "libpandabase/macros.h" @@ -53,8 +47,6 @@ class ObjectFactory; class RegExpParserCache; class EcmaRuntimeStat; class MemManager; -class Heap; -class HeapTracker; class JSNativePointer; class Program; class JSPromise; @@ -104,7 +96,7 @@ public: explicit EcmaVM(JSRuntimeOptions options); - static Expected Create(Runtime *runtime, const JSRuntimeOptions &options); + static Expected Create(Runtime *runtime, const JSRuntimeOptions &options); EcmaVM(); @@ -193,11 +185,6 @@ public: return mm_->GetMemStats(); } - GCStats *GetEcmaGCStats() const - { - return gcStats_; - } - panda::mem::GlobalObjectStorage *GetGlobalObjectStorage() const override { return nullptr; @@ -373,26 +360,7 @@ public: void Iterate(const RootVisitor &v); - const Heap *GetHeap() const - { - return heap_; - } - - void CollectGarbage(TriggerGCType gcType) const; - - void StartHeapTracking(HeapTracker *tracker); - - void StopHeapTracking(); - - RegionFactory *GetRegionFactory() const - { - return regionFactory_.get(); - } - - Chunk *GetChunk() const - { - return const_cast(&chunk_); - } + void CollectGarbage() const; void ProcessReferences(const WeakRootVisitor &v0); void HandleEnqueueReferences() override; @@ -427,7 +395,7 @@ public: coretypes::String *GetNonMovableString(const panda_file::File &pf, panda_file::File::EntityId id) const override; - const ChunkVector &GetNativeMethods() const + const PandaVector &GetNativeMethods() const { return nativeMethods_; } @@ -483,18 +451,6 @@ protected: private: static constexpr uint32_t THREAD_SLEEP_TIME = 16 * 1000; static constexpr uint32_t THREAD_SLEEP_COUNT = 100; - class TrimNewSpaceLimitTask : public Task { - public: - explicit TrimNewSpaceLimitTask(Heap *heap) : heap_(heap) {}; - ~TrimNewSpaceLimitTask() override = default; - bool Run(uint32_t threadIndex) override; - - NO_COPY_SEMANTIC(TrimNewSpaceLimitTask); - NO_MOVE_SEMANTIC(TrimNewSpaceLimitTask); - - private: - Heap *heap_; - }; void AddPandaFile(const panda_file::File *pf, bool isModule); void SetProgram(Program *program, const panda_file::File *pf); @@ -507,14 +463,14 @@ private: bool Execute(std::unique_ptr pf, std::string_view entryPoint, const std::vector &args, bool isModule = false); - Expected InvokeEcmaEntrypoint(const panda_file::File &pf, const CString &methodName, + Expected InvokeEcmaEntrypoint(const panda_file::File &pf, const PandaString &methodName, const std::vector &args); void InitializeEcmaScriptRunStat(); void RedirectMethod(const panda_file::File &pf); - bool VerifyFilePath(const CString &filePath) const; + bool VerifyFilePath(const PandaString &filePath) const; void ClearBufferData(); @@ -538,18 +494,12 @@ private: static JSRuntimeOptions options_; bool icEnable_ {true}; bool vmInitialized_ {false}; - GCStats *gcStats_ {nullptr}; - bool snapshotSerializeEnable_ {false}; - bool snapshotDeserializeEnable_ {false}; bool isUncaughtExceptionRegistered_ {false}; // VM memory management. EcmaStringTable *stringTable_ {nullptr}; - std::unique_ptr regionFactory_; - Chunk chunk_; - Heap *heap_ {nullptr}; ObjectFactory *factory_ {nullptr}; - CVector arrayBufferDataList_; + PandaVector arrayBufferDataList_; // VM execution states. JSThread *thread_ {nullptr}; @@ -562,17 +512,16 @@ private: // App framework resources. JSTaggedValue frameworkProgram_ {JSTaggedValue::Hole()}; - CString frameworkAbcFileName_; + PandaString frameworkAbcFileName_; const panda_file::File *frameworkPandaFile_ {nullptr}; - CVector frameworkProgramMethods_; + PandaVector frameworkProgramMethods_; // VM resources. - CString snapshotFileName_; - ChunkVector nativeMethods_; + PandaVector nativeMethods_ {}; ModuleManager *moduleManager_ {nullptr}; bool optionalLogEnabled_ {false}; // weak reference need Redirect address - CVector> pandaFileWithProgram_ + PandaVector> pandaFileWithProgram_ GUARDED_BY(pandaFileWithProgramLock_); mutable os::memory::Mutex pandaFileWithProgramLock_; PandaMap>> @@ -583,7 +532,7 @@ private: // Debugger RuntimeNotificationManager *notificationManager_ {nullptr}; - CUnorderedMap> extractorCache_; + PandaUnorderedMap> extractorCache_; // Registered Callbacks PromiseRejectCallback promiseRejectCallback_ {nullptr}; @@ -591,9 +540,7 @@ private: void *data_ {nullptr}; PandaList finalization_registries_; - friend class SnapShotSerialize; friend class ObjectFactory; - friend class ValueSerializer; friend class panda::JSNApi; }; } // namespace ecmascript diff --git a/runtime/frames.h b/runtime/frames.h index 465de0ea488ef112d8d1247175fc0d8c1b587912..e4135d53cccf4a51c30c80e430f3f298066fca0d 100644 --- a/runtime/frames.h +++ b/runtime/frames.h @@ -169,40 +169,6 @@ public: static constexpr int ARM32_SLOT_SIZE = sizeof(uint32_t); }; -class OptimizedFrameBase { -public: - OptimizedFrameBase() = default; - ~OptimizedFrameBase() = default; - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - FrameType type; - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - JSTaggedType *prev; // for llvm :c-fp ; for interrupt: thread-fp for gc - static OptimizedFrameBase *GetFrameFromSp(JSTaggedType *sp) - { - return reinterpret_cast(reinterpret_cast(sp) - - MEMBER_OFFSET(OptimizedFrameBase, prev)); - } - DEFAULT_MOVE_SEMANTIC(OptimizedFrameBase); - DEFAULT_COPY_SEMANTIC(OptimizedFrameBase); -}; - -class OptimizedEntryFrame { -public: - OptimizedEntryFrame() = default; - ~OptimizedEntryFrame() = default; - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - JSTaggedType *prevInterpretedFrameFp; - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - OptimizedFrameBase base; - static OptimizedEntryFrame *GetFrameFromSp(JSTaggedType *sp) - { - return reinterpret_cast(reinterpret_cast(sp) - - MEMBER_OFFSET(OptimizedEntryFrame, base.prev)); - } - DEFAULT_MOVE_SEMANTIC(OptimizedEntryFrame); - DEFAULT_COPY_SEMANTIC(OptimizedEntryFrame); -}; - class InterpretedFrameBase { public: InterpretedFrameBase() = default; diff --git a/runtime/global_dictionary-inl.h b/runtime/global_dictionary-inl.h index ce7f9b88afe7d4ec91c642e7a0792ac02d1644b7..57a7b4935cd268ba2c4949bb4679841889a06a63 100644 --- a/runtime/global_dictionary-inl.h +++ b/runtime/global_dictionary-inl.h @@ -18,7 +18,6 @@ #include "plugins/ecmascript/runtime/global_dictionary.h" #include "plugins/ecmascript/runtime/ic/property_box.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "plugins/ecmascript/runtime/tagged_hash_table-inl.h" namespace panda::ecmascript { @@ -100,7 +99,7 @@ void GlobalDictionary::GetAllKeys(const JSThread *thread, int offset, TaggedArra int arrayIndex = 0; int size = Size(); - CVector> sortArr; + PandaVector> sortArr; for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key = GetKey(hashIndex); if (!key.IsUndefined() && !key.IsHole()) { @@ -124,7 +123,7 @@ void GlobalDictionary::GetEnumAllKeys(const JSThread *thread, int offset, Tagged int arrayIndex = 0; int size = Size(); - CVector> sortArr; + PandaVector> sortArr; for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key = GetKey(hashIndex); if (key.IsString()) { diff --git a/runtime/hprof/heap_profiler.cpp b/runtime/hprof/heap_profiler.cpp deleted file mode 100644 index 0f3178b203db82606a12600acecc68b812335fdc..0000000000000000000000000000000000000000 --- a/runtime/hprof/heap_profiler.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/hprof/heap_profiler.h" - -#include -#include -#include - -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/hprof/heap_snapshot.h" -#include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/assert_scope-inl.h" -#include "plugins/ecmascript/runtime/mem/concurrent_sweeper.h" -#include "plugins/ecmascript/runtime/mem/heap-inl.h" - -namespace panda::ecmascript { -HeapProfiler::~HeapProfiler() -{ - ClearSnapShot(); - const_cast(heap_->GetRegionFactory())->Delete(jsonSerializer_); - jsonSerializer_ = nullptr; -} - -bool HeapProfiler::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const std::string &filePath, bool isVmMode) -{ - [[maybe_unused]] bool heapClean = ForceFullGC(thread); - ASSERT(heapClean); - size_t heapSize = thread->GetEcmaVM()->GetHeap()->GetHeapObjectSize(); - LOG(ERROR, RUNTIME) << "HeapProfiler DumpSnapshot heap size " << heapSize; - HeapSnapShot *snapShot = MakeHeapSnapShot(thread, SampleType::ONE_SHOT, isVmMode); - ASSERT(snapShot != nullptr); - std::pair realPath = FilePathValid(filePath); - if (realPath.first) { - return jsonSerializer_->Serialize(snapShot, realPath.second); - } - - std::pair realGenPath = FilePathValid(GenDumpFileName(dumpFormat)); - if (realGenPath.first) { - return jsonSerializer_->Serialize(snapShot, realGenPath.second); - } - UNREACHABLE(); -} - -// NOLINTNEXTLINE(google-default-arguments) -bool HeapProfiler::StartHeapTracking(JSThread *thread, double timeInterval, bool isVmMode) -{ - HeapSnapShot *snapShot = MakeHeapSnapShot(thread, SampleType::REAL_TIME, isVmMode); - if (snapShot == nullptr) { - return false; - } - heapTracker_ = std::make_unique(snapShot, timeInterval); - thread->GetEcmaVM()->StartHeapTracking(heapTracker_.get()); - heapTracker_->StartTracing(); - return true; -} - -bool HeapProfiler::StopHeapTracking(JSThread *thread, [[maybe_unused]] DumpFormat dumpFormat, const std::string &path) -{ - if (heapTracker_ == nullptr) { - return false; - } - thread->GetEcmaVM()->StopHeapTracking(); - heapTracker_->StopTracing(); - - // check path - if (path.empty()) { - return false; - } - std::pair realPath = FilePathValid(path); - if (!realPath.first) { - return false; - } - - HeapSnapShot *snapShot = hprofs_.at(0); - if (snapShot == nullptr) { - return false; - } - snapShot->FinishSnapShot(); - return jsonSerializer_->Serialize(snapShot, realPath.second); -} - -std::pair HeapProfiler::FilePathValid(const std::string &filePath) -{ - if (filePath.size() > PATH_MAX) { - return std::make_pair(false, ""); - } - CVector resolvedPath(PATH_MAX); - auto result = realpath(filePath.c_str(), resolvedPath.data()); - if (result == resolvedPath.data() || errno == ENOENT) { - return std::make_pair(true, CString(resolvedPath.data())); - } - return std::make_pair(false, ""); -} - -std::string HeapProfiler::GenDumpFileName(DumpFormat dumpFormat) -{ - CString filename("hprof_"); - switch (dumpFormat) { - case DumpFormat::JSON: - filename.append(GetTimeStamp()); - break; - case DumpFormat::BINARY: - filename.append("unimplemented"); - break; - case DumpFormat::OTHER: - filename.append("unimplemented"); - break; - default: - filename.append("unimplemented"); - break; - } - filename.append(".heapsnapshot"); - return CstringConvertToString(filename); -} - -CString HeapProfiler::GetTimeStamp() -{ - std::time_t timeSource = std::time(nullptr); - tm *timeData = localtime(&timeSource); - CString stamp; - const int TIME_START = 1900; - stamp.append(ToCString(timeData->tm_year + TIME_START)) - .append("-") - .append(ToCString(timeData->tm_mon + 1)) - .append("-") - .append(ToCString(timeData->tm_mday)) - .append("_") - .append(ToCString(timeData->tm_hour)) - .append("-") - .append(ToCString(timeData->tm_min)) - .append("-") - .append(ToCString(timeData->tm_sec)); - return stamp; -} - -bool HeapProfiler::ForceFullGC(JSThread *thread) -{ - auto vm = thread->GetEcmaVM(); - if (vm->IsInitialized()) { - const_cast(vm->GetHeap())->CollectGarbage(TriggerGCType::SEMI_GC); - const_cast(vm->GetHeap())->CollectGarbage(TriggerGCType::OLD_GC); - return true; - } - return false; -} - -HeapSnapShot *HeapProfiler::MakeHeapSnapShot(JSThread *thread, SampleType sampleType, bool isVmMode) -{ - LOG(ERROR, RUNTIME) << "HeapProfiler::MakeHeapSnapShot"; - DISALLOW_GARBAGE_COLLECTION; - heap_->GetSweeper()->EnsureAllTaskFinished(); - switch (sampleType) { - case SampleType::ONE_SHOT: { - auto *snapShot = - const_cast(heap_->GetRegionFactory())->New(thread, heap_, isVmMode); - if (snapShot == nullptr) { - LOG_ECMA(FATAL) << "alloc snapshot failed"; - UNREACHABLE(); - } - snapShot->BuildUp(thread); - AddSnapShot(snapShot); - return snapShot; - } - case SampleType::REAL_TIME: { - auto *snapShot = - const_cast(heap_->GetRegionFactory())->New(thread, heap_, isVmMode); - if (snapShot == nullptr) { - LOG_ECMA(FATAL) << "alloc snapshot failed"; - UNREACHABLE(); - } - AddSnapShot(snapShot); - snapShot->PrepareSnapShot(); - return snapShot; - } - default: - return nullptr; - } -} - -void HeapProfiler::AddSnapShot(HeapSnapShot *snapshot) -{ - if (hprofs_.size() >= MAX_NUM_HPROF) { - ClearSnapShot(); - } - ASSERT(snapshot != nullptr); - hprofs_.emplace_back(snapshot); -} - -void HeapProfiler::ClearSnapShot() -{ - for (auto *snapshot : hprofs_) { - const_cast(heap_->GetRegionFactory())->Delete(snapshot); - } - hprofs_.clear(); -} -} // namespace panda::ecmascript diff --git a/runtime/hprof/heap_profiler.h b/runtime/hprof/heap_profiler.h deleted file mode 100644 index 4395cb51492e3796ea280c724291c3e16e518dcc..0000000000000000000000000000000000000000 --- a/runtime/hprof/heap_profiler.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_HPROF_HEAP_PROFILER_H -#define ECMASCRIPT_HPROF_HEAP_PROFILER_H - -#include "plugins/ecmascript/runtime/ecma_macros.h" -#include "plugins/ecmascript/runtime/hprof/heap_profiler_interface.h" -#include "plugins/ecmascript/runtime/hprof/heap_snapshot_json_serializer.h" -#include "plugins/ecmascript/runtime/hprof/heap_tracker.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "os/mem.h" - -namespace panda::ecmascript { -class HeapSnapShot; -class HeapProfiler : public HeapProfilerInterface { -public: - NO_MOVE_SEMANTIC(HeapProfiler); - NO_COPY_SEMANTIC(HeapProfiler); - explicit HeapProfiler(const Heap *heap) : heap_(heap) - { - jsonSerializer_ = const_cast(heap->GetRegionFactory())->New(); - if (UNLIKELY(jsonSerializer_ == nullptr)) { - LOG_ECMA(FATAL) << "alloc snapshot json serializer failed"; - UNREACHABLE(); - } - } - ~HeapProfiler() override; - - enum class SampleType { ONE_SHOT, REAL_TIME }; - /** - * dump the specific snapshot in target format - */ - bool DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const std::string &path, bool isVmMode = true); - void AddSnapShot(HeapSnapShot *snapshot); - - // NOLINTNEXTLINE(google-default-arguments) - bool StartHeapTracking(JSThread *thread, double timeInterval, bool isVmMode = true) override; - bool StopHeapTracking(JSThread *thread, DumpFormat dumpFormat, const std::string &filePath) override; - -private: - /** - * tigger full gc to make sure no unreachable objects in heap - */ - bool ForceFullGC(JSThread *thread); - - /** - * make a new heap snapshot and put it into a container eg, vector - */ - HeapSnapShot *MakeHeapSnapShot(JSThread *thread, SampleType sampleType, bool isVmMode = true); - std::pair FilePathValid(const std::string &filePath); - std::string GenDumpFileName(DumpFormat dumpFormat); - CString GetTimeStamp(); - void ClearSnapShot(); - - const size_t MAX_NUM_HPROF = 5; // ~10MB - CVector hprofs_; - HeapSnapShotJSONSerializer *jsonSerializer_ {nullptr}; - std::unique_ptr heapTracker_; - const Heap *heap_; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_HPROF_HEAP_PROFILER_H diff --git a/runtime/hprof/heap_profiler_interface.cpp b/runtime/hprof/heap_profiler_interface.cpp deleted file mode 100644 index 9cb907f0fc3bcdacdb4bf9a1d714f013f702ff1f..0000000000000000000000000000000000000000 --- a/runtime/hprof/heap_profiler_interface.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/hprof/heap_profiler.h" -#include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/heap.h" - -namespace panda::ecmascript { -HeapProfilerInterface *HeapProfilerInterface::heapProfile_ = nullptr; -HeapProfilerInterface *HeapProfilerInterface::GetInstance(JSThread *thread) -{ - if (HeapProfilerInterface::heapProfile_ == nullptr) { - heapProfile_ = HeapProfilerInterface::CreateHeapProfiler(thread); - } - return HeapProfilerInterface::heapProfile_; -} - -void HeapProfilerInterface::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const std::string &filePath, - bool isVmMode) -{ - LOG(ERROR, RUNTIME) << "HeapProfilerInterface::DumpHeapSnapshot"; - const Heap *heap = thread->GetEcmaVM()->GetHeap(); - auto *hprof = const_cast(heap->GetRegionFactory())->New(heap); - if (UNLIKELY(hprof == nullptr)) { - LOG_ECMA(FATAL) << "alloc hprof failed"; - UNREACHABLE(); - } - hprof->DumpHeapSnapShot(thread, dumpFormat, filePath, isVmMode); - const_cast(heap->GetRegionFactory())->Delete(hprof); -} - -HeapProfilerInterface *HeapProfilerInterface::CreateHeapProfiler(JSThread *thread) -{ - const Heap *heap = thread->GetEcmaVM()->GetHeap(); - auto *hprof = const_cast(heap->GetRegionFactory())->New(heap); - ASSERT(hprof != nullptr); - return hprof; -} - -void HeapProfilerInterface::Destroy(JSThread *thread, HeapProfilerInterface *heapProfiler) -{ - const Heap *heap = thread->GetEcmaVM()->GetHeap(); - const_cast(heap->GetRegionFactory())->Delete(heapProfiler); -} -} // namespace panda::ecmascript diff --git a/runtime/hprof/heap_profiler_interface.h b/runtime/hprof/heap_profiler_interface.h deleted file mode 100644 index a338c65fc76d86608614b659ed4573999f0d50b3..0000000000000000000000000000000000000000 --- a/runtime/hprof/heap_profiler_interface.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_HPROF_HEAP_PROFILER_INTERFACE_H -#define ECMASCRIPT_HPROF_HEAP_PROFILER_INTERFACE_H - -#include "plugins/ecmascript/runtime/mem/c_string.h" -#include "plugins/ecmascript/runtime/js_thread.h" - -namespace panda::ecmascript { -enum class DumpFormat { JSON, BINARY, OTHER }; - -class HeapProfilerInterface { -public: - static HeapProfilerInterface *GetInstance(JSThread *thread); - static void DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const std::string &filePath, - bool isVmMode = true); - - static HeapProfilerInterface *CreateHeapProfiler(JSThread *thread); - static void Destroy(JSThread *thread, HeapProfilerInterface *heapProfiler); - - HeapProfilerInterface() = default; - virtual ~HeapProfilerInterface() = default; - - // NOLINTNEXTLINE(google-default-arguments) - virtual bool StartHeapTracking(JSThread *thread, double timeInterval, bool isVmMode = true) = 0; - virtual bool StopHeapTracking(JSThread *thread, DumpFormat dumpFormat, const std::string &filePath) = 0; - - NO_MOVE_SEMANTIC(HeapProfilerInterface); - NO_COPY_SEMANTIC(HeapProfilerInterface); - -private: - static HeapProfilerInterface *heapProfile_; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_HPROF_HEAP_PROFILER_INTERFACE_H diff --git a/runtime/hprof/heap_root_visitor.cpp b/runtime/hprof/heap_root_visitor.cpp deleted file mode 100644 index 16de662d7a55b1e6086bdeb5aeb420b0fba967e0..0000000000000000000000000000000000000000 --- a/runtime/hprof/heap_root_visitor.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/hprof/heap_root_visitor.h" -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/js_thread.h" - -namespace panda::ecmascript { -void HeapRootVisitor::VisitHeapRoots(JSThread *thread, const RootVisitor &visitor, - const RootRangeVisitor &range_visitor) -{ - auto ecma_vm = GetVMInstance(thread); - ecma_vm->Iterate(visitor); - thread->Iterate(visitor, range_visitor); -} - -EcmaVM *HeapRootVisitor::GetVMInstance(JSThread *thread) const -{ - return thread->GetEcmaVM(); -} -} // namespace panda::ecmascript diff --git a/runtime/hprof/heap_root_visitor.h b/runtime/hprof/heap_root_visitor.h deleted file mode 100644 index 0f1f44b33ec7cfb86058c9a586d8b37a3423d9e1..0000000000000000000000000000000000000000 --- a/runtime/hprof/heap_root_visitor.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_HPROF_HEAP_ROOT_VISITOR_H -#define ECMASCRIPT_HPROF_HEAP_ROOT_VISITOR_H - -#include "plugins/ecmascript/runtime/mem/object_xray.h" - -namespace panda::ecmascript { -class JSThread; - -class HeapRootVisitor { -public: - HeapRootVisitor() = default; - ~HeapRootVisitor() = default; - NO_MOVE_SEMANTIC(HeapRootVisitor); - NO_COPY_SEMANTIC(HeapRootVisitor); - void VisitHeapRoots(JSThread *thread, const RootVisitor &visitor, const RootRangeVisitor &range_visitor); - -private: - EcmaVM *GetVMInstance(JSThread *thread) const; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_HPROF_HEAP_ROOT_VISITOR_H diff --git a/runtime/hprof/heap_snapshot.cpp b/runtime/hprof/heap_snapshot.cpp deleted file mode 100644 index 74bf6b08ebc1d6e0dfe2eb7f6e8a03ec464fcec4..0000000000000000000000000000000000000000 --- a/runtime/hprof/heap_snapshot.cpp +++ /dev/null @@ -1,737 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/hprof/heap_snapshot.h" - -#include - -#include "plugins/ecmascript/runtime/ecma_string-inl.h" -#include "plugins/ecmascript/runtime/global_dictionary.h" -#include "plugins/ecmascript/runtime/global_env.h" -#include "plugins/ecmascript/runtime/hprof/heap_root_visitor.h" -#include "plugins/ecmascript/runtime/ic/property_box.h" -#include "plugins/ecmascript/runtime/js_array.h" -#include "plugins/ecmascript/runtime/js_handle.h" -#include "plugins/ecmascript/runtime/js_hclass-inl.h" -#include "plugins/ecmascript/runtime/js_object-inl.h" -#include "plugins/ecmascript/runtime/js_symbol.h" -#include "plugins/ecmascript/runtime/js_tagged_value-inl.h" -#include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/assert_scope-inl.h" -#include "plugins/ecmascript/runtime/property_attributes.h" -#include "plugins/ecmascript/runtime/tagged_array.h" -#include "plugins/ecmascript/runtime/tagged_dictionary.h" - -namespace panda::ecmascript { -CString *HeapSnapShot::GetString(const CString &as) -{ - return stringTable_.GetString(as); -} - -Node *Node::NewNode(const Heap *heap, size_t id, size_t index, CString *name, NodeType type, size_t size, - TaggedObject *entry, bool isLive) -{ - auto node = const_cast(heap->GetRegionFactory()) - ->New(id, index, name, type, size, 0, NewAddress(entry), isLive); - if (UNLIKELY(node == nullptr)) { - LOG_ECMA(FATAL) << "internal allocator failed"; - UNREACHABLE(); - } - return node; -} - -Edge *Edge::NewEdge(const Heap *heap, uint64_t id, EdgeType type, Node *from, Node *to, CString *name) -{ - auto edge = const_cast(heap->GetRegionFactory())->New(id, type, from, to, name); - if (UNLIKELY(edge == nullptr)) { - LOG_ECMA(FATAL) << "internal allocator failed"; - UNREACHABLE(); - } - return edge; -} - -HeapSnapShot::~HeapSnapShot() -{ - const Heap *heap = thread_->GetEcmaVM()->GetHeap(); - for (Node *node : nodes_) { - const_cast(heap->GetRegionFactory())->Delete(node); - } - for (Edge *edge : edges_) { - const_cast(heap->GetRegionFactory())->Delete(edge); - } - nodes_.clear(); - edges_.clear(); -} - -bool HeapSnapShot::BuildUp(JSThread *thread) -{ - FillNodes(thread); - FillEdges(thread); - AddSyntheticRoot(thread); - return Verify(); -} - -bool HeapSnapShot::Verify() -{ - GetString(CString("HeapVerify:").append(ToCString(totalNodesSize_))); - return (edgeCount_ > nodeCount_) && (totalNodesSize_ > 0); -} - -void HeapSnapShot::PrepareSnapShot() -{ - FillNodes(thread_); -} - -void HeapSnapShot::UpdateNode() -{ - for (Node *node : nodes_) { - node->SetLive(false); - } - FillNodes(thread_); - - for (auto iter = nodes_.begin(); iter != nodes_.end();) { - if (!(*iter)->IsLive()) { - iter = nodes_.erase(iter); - } else { - iter++; - } - } -} - -bool HeapSnapShot::FinishSnapShot() -{ - UpdateNode(); - FillEdges(thread_); - AddSyntheticRoot(thread_); - return Verify(); -} - -void HeapSnapShot::RecordSampleTime() -{ - timeStamps_.emplace_back(sequenceId_); -} - -void HeapSnapShot::AddNode(uintptr_t address) -{ - GenerateNode(thread_, JSTaggedValue(address)); -} - -void HeapSnapShot::MoveNode(uintptr_t address, uintptr_t forward_address) -{ - int sequenceId = -1; - Node *node = entryMap_.FindAndEraseNode(address); - if (node != nullptr) { - sequenceId = node->GetId(); - EraseNodeUnique(node); - } - GenerateNode(thread_, JSTaggedValue(forward_address), sequenceId); -} - -// NOLINTNEXTLINE(readability-function-size) -CString *HeapSnapShot::GenerateNodeName([[maybe_unused]] JSThread *thread, const JSHandle &entry) -{ - auto *hCls = entry->GetClass(); - JSType type = hCls->GetObjectType(); - switch (type) { - case JSType::TAGGED_ARRAY: { - CString arrayName; - TaggedArray *array = TaggedArray::Cast(entry.GetObject()); - arrayName = "TaggedArray["; - arrayName.append(ToCString(array->GetLength())); - arrayName.append("]"); - return GetString(arrayName); // String type was handled singly, see#GenerateStringNode - } - case JSType::HCLASS: - return GetString("HiddenClass"); - case JSType::TAGGED_DICTIONARY: { - CString dictName; - TaggedArray *dict = TaggedArray::Cast(entry.GetObject()); - dictName = "TaggedDict["; - dictName.append(ToCString(dict->GetLength())); - dictName.append("]"); - return GetString(dictName); - } - case JSType::STRING: - return GetString("BaseString"); - case JSType::JS_OBJECT: { - CString objName = CString("JSOBJECT(Ctor="); // Ctor-name - return GetString(objName); - } - 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; - } - case JSType::JS_FUNCTION_BASE: - return GetString("JSFunctionBase"); - case JSType::JS_FUNCTION: - return GetString("JSFunction"); - case JSType::JS_ERROR: - return GetString("Error"); - case JSType::JS_EVAL_ERROR: - return GetString("Eval Error"); - case JSType::JS_RANGE_ERROR: - return GetString("Range Error"); - case JSType::JS_TYPE_ERROR: - return GetString("Type Error"); - case JSType::JS_REFERENCE_ERROR: - return GetString("Reference Error"); - case JSType::JS_URI_ERROR: - return GetString("Uri Error"); - case JSType::JS_SYNTAX_ERROR: - return GetString("Syntax Error"); - case JSType::JS_REG_EXP: - return GetString("Regexp"); - case JSType::JS_SET: - return GetString("Set"); - case JSType::JS_MAP: - return GetString("Map"); - case JSType::JS_WEAK_SET: - return GetString("WeakSet"); - case JSType::JS_WEAK_MAP: - return GetString("WeakMap"); - case JSType::JS_DATE: - return GetString("Date"); - case JSType::JS_BOUND_FUNCTION: - return GetString("Bound Function"); - case JSType::JS_ARRAY: { - JSArray *jsArray = JSArray::Cast(entry.GetObject()); - CString jsArrayName("JSArray["); - jsArrayName.append(ToCString(jsArray->GetLength().GetInt())); - jsArrayName.append("]"); - return GetString(jsArrayName); - } - case JSType::JS_TYPED_ARRAY: - return GetString("Typed Array"); - case JSType::JS_INT8_ARRAY: - return GetString("Int8 Array"); - case JSType::JS_UINT8_ARRAY: - return GetString("Uint8 Array"); - case JSType::JS_UINT8_CLAMPED_ARRAY: - return GetString("Uint8 Clamped Array"); - case JSType::JS_INT16_ARRAY: - return GetString("Int16 Array"); - case JSType::JS_UINT16_ARRAY: - return GetString("Uint16 Array"); - case JSType::JS_INT32_ARRAY: - return GetString("Int32 Array"); - case JSType::JS_UINT32_ARRAY: - return GetString("Uint32 Array"); - case JSType::JS_FLOAT32_ARRAY: - return GetString("Float32 Array"); - case JSType::JS_FLOAT64_ARRAY: - return GetString("Float64 Array"); - case JSType::JS_ARGUMENTS: - return GetString("Arguments"); - case JSType::JS_PROXY: - return GetString("Proxy"); - case JSType::JS_PRIMITIVE_REF: - return GetString("Primitive"); - case JSType::JS_DATA_VIEW: - return GetString("DataView"); - case JSType::JS_ITERATOR: - return GetString("Iterator"); - case JSType::JS_FORIN_ITERATOR: - return GetString("ForinInterator"); - case JSType::JS_MAP_ITERATOR: - return GetString("MapIterator"); - case JSType::JS_SET_ITERATOR: - return GetString("SetIterator"); - case JSType::JS_ARRAY_ITERATOR: - return GetString("ArrayIterator"); - case JSType::JS_STRING_ITERATOR: - return GetString("StringIterator"); - case JSType::JS_ARRAY_BUFFER: - return GetString("ArrayBuffer"); - case JSType::JS_PROXY_REVOC_FUNCTION: - return GetString("ProxyRevocFunction"); - case JSType::PROMISE_REACTIONS: - return GetString("PromiseReaction"); - case JSType::PROMISE_CAPABILITY: - return GetString("PromiseCapability"); - case JSType::PROMISE_ITERATOR_RECORD: - return GetString("PromiseIteratorRecord"); - case JSType::PROMISE_RECORD: - return GetString("PromiseRecord"); - case JSType::RESOLVING_FUNCTIONS_RECORD: - return GetString("ResolvingFunctionsRecord"); - case JSType::JS_PROMISE: - return GetString("Promise"); - case JSType::JS_PROMISE_REACTIONS_FUNCTION: - return GetString("PromiseReactionsFunction"); - case JSType::JS_PROMISE_EXECUTOR_FUNCTION: - return GetString("PromiseExecutorFunction"); - case JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION: - return GetString("PromiseAllResolveElementFunction"); - case JSType::JS_GENERATOR_FUNCTION: - return GetString("JSGeneratorFunction"); - case JSType::SYMBOL: - return GetString("Symbol"); - case JSType::JS_ASYNC_FUNCTION: - return GetString("AsyncFunction"); - case JSType::JS_INTL_BOUND_FUNCTION: - return GetString("JSIntlBoundFunction"); - case JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION: - return GetString("AsyncAwaitStatusFunction"); - case JSType::JS_ASYNC_FUNC_OBJECT: - return GetString("AsyncFunctionObject"); - case JSType::JS_REALM: - return GetString("Realm"); - case JSType::JS_GLOBAL_OBJECT: - return GetString("GlobalObject"); - case JSType::JS_INTL: - return GetString("JSIntl"); - case JSType::JS_LOCALE: - return GetString("JSLocale"); - case JSType::JS_DATE_TIME_FORMAT: - return GetString("JSDateTimeFormat"); - case JSType::JS_RELATIVE_TIME_FORMAT: - return GetString("JSRelativeTimeFormat"); - case JSType::JS_NUMBER_FORMAT: - return GetString("JSNumberFormat"); - case JSType::JS_COLLATOR: - return GetString("JSCollator"); - case JSType::JS_PLURAL_RULES: - return GetString("JSPluralRules"); - case JSType::JS_GENERATOR_OBJECT: - return GetString("JSGeneratorObject"); - case JSType::JS_GENERATOR_CONTEXT: - return GetString("JSGeneratorContext"); - case JSType::ACCESSOR_DATA: - return GetString("AccessorData"); - case JSType::INTERNAL_ACCESSOR: - return GetString("InternalAccessor"); - case JSType::FUNCTION_EXTRA_INFO: - return GetString("FunctionExtraInfo"); - case JSType::MICRO_JOB_QUEUE: - return GetString("MicroJobQueue"); - case JSType::PENDING_JOB: - return GetString("PendingJob"); - case JSType::COMPLETION_RECORD: - return GetString("CompletionRecord"); - case JSType::ECMA_MODULE: - return GetString("EcmaModule"); - case JSType::JS_ARRAY_LIST: - return GetString("ArrayList"); - default: - break; - } - if (IsInVmMode()) { - switch (type) { - case JSType::PROPERTY_BOX: - return GetString("PropertyBox"); - case JSType::GLOBAL_ENV: - return GetString("GlobalEnv"); - case JSType::PROTOTYPE_HANDLER: - return GetString("ProtoTypeHandler"); - case JSType::TRANSITION_HANDLER: - return GetString("TransitionHandler"); - case JSType::PROTO_CHANGE_MARKER: - return GetString("ProtoChangeMarker"); - case JSType::PROTOTYPE_INFO: - return GetString("ProtoChangeDetails"); - case JSType::TEMPLATE_MAP: - return GetString("TemplateMap"); - case JSType::PROGRAM: - return GetString("Program"); - case JSType::LEXICAL_FUNCTION: - return GetString("LexicalFunction"); - case JSType::MACHINE_CODE_OBJECT: - return GetString("MachineCode"); - default: - break; - } - } else { - return GetString("Hidden Object"); - } - return GetString("UnKnownType"); -} - -NodeType HeapSnapShot::GenerateNodeType(TaggedObject *entry) -{ - NodeType nodeType = NodeType::INVALID; - auto *hCls = entry->GetClass(); - if (hCls->IsTaggedArray()) { - nodeType = NodeType::JS_ARRAY; - } else if (hCls->IsHClass()) { - nodeType = NodeType::HCLASS; - } else { - nodeType = NodeType(hCls->GetObjectType()); - } - return nodeType; -} - -void HeapSnapShot::FillNodes(JSThread *thread) -{ - // Iterate Heap Object - auto heap = thread_->GetEcmaVM()->GetHeap(); - if (heap != nullptr) { - heap->IteratorOverObjects( - [this, &thread](TaggedObject *obj) { this->GenerateNode(thread, JSTaggedValue(obj)); }); - } -} - -Node *HeapSnapShot::GenerateNode(JSThread *thread, JSTaggedValue entry, int sequenceId) -{ - Node *node = nullptr; - if (sequenceId == -1) { - sequenceId = sequenceId_ + SEQ_STEP; - } - if (entry.IsHeapObject()) { - if (entry.IsWeak()) { - entry.RemoveWeakTag(); - } - if (entry.IsString()) { - node = GenerateStringNode(entry, sequenceId); - if (node == nullptr) { - LOG(DEBUG, RUNTIME) << "string node nullptr"; - } - } - JSHandle obj(thread, entry.GetTaggedObject()); - auto *baseClass = obj->GetClass(); - if (baseClass != nullptr) { - auto name = GenerateNodeName(thread, obj); - node = Node::NewNode(heap_, sequenceId, nodeCount_, name, GenerateNodeType(obj.GetObject()), - obj->GetClass()->SizeFromJSHClass(obj.GetObject()), - obj.GetObject()); - Node *existNode = entryMap_.FindOrInsertNode(node); // Fast Index - if (existNode == node) { - if (sequenceId == sequenceId_ + SEQ_STEP) { - sequenceId_ = sequenceId; // Odd Digit - } - InsertNodeUnique(node); - ASSERT(entryMap_.FindEntry(node->GetAddress())->GetAddress() == node->GetAddress()); - } else { - existNode->SetLive(true); - ASSERT(entryMap_.FindEntry(node->GetAddress())->GetAddress() == node->GetAddress()); - const_cast(heap_->GetRegionFactory())->Delete(node); - return nullptr; - } - } - } else { - CString primitiveName; - // A primitive value with tag will be regarded as a pointer - auto *obj = reinterpret_cast(entry.GetRawData()); - if (entry.IsInt()) { - primitiveName.append("Int:" + ToCString(entry.GetInt())); - } else if (entry.IsDouble()) { - primitiveName.append("Double:"); - } else if (entry.IsHole()) { - primitiveName.append("Hole"); - } else if (entry.IsNull()) { - primitiveName.append("Null"); - } else if (entry.IsTrue()) { - primitiveName.append("Boolean:true"); - } else if (entry.IsFalse()) { - primitiveName.append("Boolean:false"); - } else if (entry.IsException()) { - primitiveName.append("Exception"); - } else if (entry.IsUndefined()) { - primitiveName.append("Undefined"); - } else { - primitiveName.append("Illegal_Primitive"); - } - - node = - Node::NewNode(heap_, sequenceId, nodeCount_, GetString(primitiveName), NodeType::JS_PRIMITIVE_REF, 0, obj); - entryMap_.InsertEntry(node); // Fast Index - if (sequenceId == sequenceId_ + SEQ_STEP) { - sequenceId_ = sequenceId; // Odd Digit - } - InsertNodeUnique(node); - } - return node; -} - -Node *HeapSnapShot::GenerateStringNode(JSTaggedValue entry, int sequenceId) -{ - Node *node = nullptr; - auto originStr = static_cast(entry.GetTaggedObject()); - size_t selfsize = originStr->ObjectSize(); - CString strContent; - strContent.append(EntryVisitor::ConvertKey(entry)); - node = Node::NewNode(heap_, sequenceId, nodeCount_, GetString(strContent), NodeType::PRIM_STRING, selfsize, - entry.GetTaggedObject()); - Node *existNode = entryMap_.FindOrInsertNode(node); // Fast Index - if (existNode == node) { - if (sequenceId == sequenceId_ + SEQ_STEP) { - sequenceId_ = sequenceId; // Odd Digit - } - InsertNodeUnique(node); - } else { - existNode->SetLive(true); - } - ASSERT(entryMap_.FindEntry(node->GetAddress())->GetAddress() == node->GetAddress()); - if (existNode != node) { - const_cast(heap_->GetRegionFactory())->Delete(node); - return nullptr; - } - return node; -} - -void HeapSnapShot::FillEdges(JSThread *thread) -{ - size_t length = nodes_.size(); - auto iter = nodes_.begin(); - size_t count = 0; - while (++count < length) { - ASSERT(*iter != nullptr); - auto *objFrom = reinterpret_cast((*iter)->GetAddress()); - std::vector> nameResources; - JSTaggedValue(objFrom).DumpForSnapshot(thread, nameResources, isVmMode_); - JSTaggedValue objValue(objFrom); - for (auto const &it : nameResources) { - JSTaggedValue toValue = it.second; - Node *entryTo = nullptr; - if (toValue.IsHeapObject()) { - auto *to = reinterpret_cast(toValue.GetHeapObject()); - entryTo = entryMap_.FindEntry(Node::NewAddress(to)); - } - if (entryTo == nullptr) { - entryTo = GenerateNode(thread, toValue); - } - if (entryTo != nullptr) { - Edge *edge = Edge::NewEdge(heap_, edgeCount_, EdgeType::DEFAULT, *iter, entryTo, GetString(it.first)); - InsertEdgeUnique(edge); - (*iter)->IncEdgeCount(); // Update Node's edgeCount_ here - } - } - iter++; - } - // Fill Primitive Edge - size_t lengthExtend = nodes_.size(); - while (++count < lengthExtend) { - ASSERT(*iter != nullptr); - if ((*iter)->GetType() == NodeType::JS_PRIMITIVE_REF) { - JSTaggedValue jsFrom(reinterpret_cast((*iter)->GetAddress())); - CString valueName; - if (jsFrom.IsInt()) { - valueName.append(ToCString(jsFrom.GetInt())); - } else if (jsFrom.IsDouble()) { - valueName.append(FloatToCString(jsFrom.GetDouble())); - } else { - valueName.append("NaN"); - } - Edge *edge = Edge::NewEdge(heap_, edgeCount_, EdgeType::DEFAULT, (*iter), (*iter), GetString(valueName)); - InsertEdgeUnique(edge); - (*iter)->IncEdgeCount(); // Update Node's edgeCount_ here - } - iter++; - } -} - -void HeapSnapShot::BridgeAllReferences() -{ - // This Function is Unused - for (Edge *edge : edges_) { - auto *from = reinterpret_cast(edge->GetFrom()->GetAddress()); - auto *to = reinterpret_cast(edge->GetTo()->GetAddress()); - if (!JSTaggedValue(from).IsECMAObject()) { - continue; // named it by other way - } - edge->SetName(GenerateEdgeName(from, to)); - } -} - -CString *HeapSnapShot::GenerateEdgeName([[maybe_unused]] TaggedObject *from, [[maybe_unused]] TaggedObject *to) -{ - // This Function is Unused - ASSERT(from != nullptr && from != to); - return GetString("[]"); // unAnalysed -} - -Node *HeapSnapShot::InsertNodeUnique(Node *node) -{ - AccumulateNodeSize(node->GetSelfSize()); - nodes_.emplace_back(node); - nodeCount_++; - return node; -} - -void HeapSnapShot::EraseNodeUnique(Node *node) -{ - auto iter = std::find(nodes_.begin(), nodes_.end(), node); - if (iter != nodes_.end()) { - DecreaseNodeSize(node->GetSelfSize()); - nodes_.erase(iter); - nodeCount_--; - } -} - -Edge *HeapSnapShot::InsertEdgeUnique(Edge *edge) -{ - edges_.emplace_back(edge); - edgeCount_++; - return edge; -} - -void HeapSnapShot::AddSyntheticRoot(JSThread *thread) -{ - Node *syntheticRoot = - Node::NewNode(heap_, 1, nodeCount_, GetString("SyntheticRoot"), NodeType::SYNTHETIC, 0, nullptr); - InsertNodeAt(0, syntheticRoot); - - int edgeOffset = 0; -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define ROOT_EDGE_BUILDER_CORE(type, slot) \ - JSTaggedValue value(slot.GetTaggedType()); \ - if (value.IsHeapObject()) { \ - TaggedObject *root = value.GetTaggedObject(); \ - Node *rootNode = entryMap_.FindEntry(Node::NewAddress(root)); \ - if (rootNode != nullptr) { \ - Edge *edge = \ - Edge::NewEdge(heap_, edgeCount_, EdgeType::SHORTCUT, syntheticRoot, rootNode, GetString("-subroot-")); \ - InsertEdgeAt(edgeOffset, edge); \ - edgeOffset++; \ - syntheticRoot->IncEdgeCount(); \ - } \ - } - - RootVisitor rootEdgeBuilder = [this, syntheticRoot, &edgeOffset]([[maybe_unused]] Root type, ObjectSlot slot) { - ROOT_EDGE_BUILDER_CORE(type, slot); - }; - - RootRangeVisitor rootRangeEdgeBuilder = [this, syntheticRoot, &edgeOffset]([[maybe_unused]] Root type, - ObjectSlot start, ObjectSlot end) { - for (ObjectSlot slot = start; slot < end; slot++) { - ROOT_EDGE_BUILDER_CORE(type, slot); - } - }; -#undef ROOT_EDGE_BUILDER_CORE - rootVisitor_.VisitHeapRoots(thread, rootEdgeBuilder, rootRangeEdgeBuilder); - - int reindex = 0; - for (Node *node : nodes_) { - node->SetIndex(reindex); - reindex++; - } -} - -Node *HeapSnapShot::InsertNodeAt(size_t pos, Node *node) -{ - ASSERT(node != nullptr); - auto iter = nodes_.begin(); - std::advance(iter, pos); - nodes_.insert(iter, node); - nodeCount_++; - return node; -} - -Edge *HeapSnapShot::InsertEdgeAt(size_t pos, Edge *edge) -{ - ASSERT(edge != nullptr); - edges_.insert(edges_.begin() + pos, edge); - edgeCount_++; - return edge; -} - -CString EntryVisitor::ConvertKey(JSTaggedValue key) -{ - ASSERT(key.GetTaggedObject() != nullptr); - EcmaString *keyString = EcmaString::Cast(key.GetTaggedObject()); - if (key.IsSymbol()) { - JSSymbol *symbol = JSSymbol::Cast(key.GetTaggedObject()); - keyString = EcmaString::Cast(symbol->GetDescription().GetTaggedObject()); - } - // convert, expensive but safe - int length = 0; - if (keyString->IsUtf8()) { - length = keyString->GetUtf8Length(); - std::vector buffer(length); - [[maybe_unused]] int size = keyString->CopyDataUtf8(buffer.data(), length); - ASSERT(size == length); - CString keyCopy(reinterpret_cast(buffer.data())); - return keyCopy; - } - length = keyString->GetLength(); - std::vector buffer(length); - [[maybe_unused]] int size = keyString->CopyDataUtf16(buffer.data(), length); - ASSERT(size == length); - CString keyCopy(reinterpret_cast(buffer.data())); - return keyCopy; -} - -Node *HeapEntryMap::FindOrInsertNode(Node *node) -{ - ASSERT(node != nullptr); - auto it = nodesMap_.find(node->GetAddress()); - if (it != nodesMap_.end()) { - return it->second; - } - InsertEntry(node); - return node; -} - -Node *HeapEntryMap::FindAndEraseNode(Address addr) -{ - auto it = nodesMap_.find(addr); - if (it != nodesMap_.end()) { - Node *node = it->second; - nodesMap_.erase(it); - nodeEntryCount_--; - return node; - } - return nullptr; -} - -Node *HeapEntryMap::FindEntry(Address addr) -{ - auto it = nodesMap_.find(addr); - return it != nodesMap_.end() ? it->second : nullptr; -} - -void HeapEntryMap::InsertEntry(Node *node) -{ - nodeEntryCount_++; - nodesMap_.insert(std::make_pair(node->GetAddress(), node)); -} - -FrontType NodeTypeConverter::Convert(NodeType type) -{ - FrontType fType = FrontType::DEFAULT; - if (type == NodeType::PROPERTY_BOX) { - fType = FrontType::HIDDEN; - } else if (type == NodeType::JS_ARRAY || type == NodeType::JS_TYPED_ARRAY) { - fType = FrontType::ARRAY; - } else if (type == NodeType::PRIM_STRING) { // STRING - fType = FrontType::STRING; - } else if (type == NodeType::JS_OBJECT) { - fType = FrontType::OBJECT; - } else if (type >= NodeType::JS_FUNCTION_BEGIN && type <= NodeType::JS_FUNCTION_END) { - fType = FrontType::CLOSURE; - } else if (type == NodeType::JS_BOUND_FUNCTION) { - fType = FrontType::CLOSURE; - } else if (type == NodeType::JS_FUNCTION_BASE) { - fType = FrontType::CLOSURE; - } else if (type == NodeType::JS_REG_EXP) { - fType = FrontType::REGEXP; - } else if (type == NodeType::SYMBOL) { - fType = FrontType::SYMBOL; - } else if (type == NodeType::JS_PRIMITIVE_REF) { - fType = FrontType::HEAPNUMBER; - } else if (type == NodeType::SYNTHETIC) { - fType = FrontType::SYNTHETIC; - } else { - fType = FrontType::DEFAULT; - // NATIVE, /* kNative */ - // CONSSTRING, /* kConsString */ - // SLICEDSTRING, /* kSlicedString */ - // SYMBOL, /* kSymbol */ - // BIGINT, /* kBigInt */ - } - return fType; -} -} // namespace panda::ecmascript diff --git a/runtime/hprof/heap_snapshot.h b/runtime/hprof/heap_snapshot.h deleted file mode 100644 index f3992946bf6e00403de0d6610083a7700b922d7b..0000000000000000000000000000000000000000 --- a/runtime/hprof/heap_snapshot.h +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_HPROF_HEAP_SNAPSHOT_H -#define ECMASCRIPT_HPROF_HEAP_SNAPSHOT_H - -#include -#include -#include -#include - -#include "plugins/ecmascript/runtime/mem/c_containers.h" -#include "os/mem.h" -#include "plugins/ecmascript/runtime/hprof/heap_profiler.h" -#include "plugins/ecmascript/runtime/hprof/heap_root_visitor.h" -#include "plugins/ecmascript/runtime/hprof/string_hashmap.h" -#include "plugins/ecmascript/runtime/js_hclass.h" -#include "plugins/ecmascript/runtime/js_object.h" -#include "plugins/ecmascript/runtime/js_tagged_value.h" - -namespace panda::ecmascript { -// Define the Object Graphic -using Address = uintptr_t; - -enum class NodeType : uint8_t { - JSTYPE_DECL, - PRIM_STRING, /* Primitive String */ - PRIM_ARRAY, /* Primitive Array */ - SYNTHETIC /* For Synthetic Root */ -}; - -enum class EdgeType { CONTEXT, ELEMENT, PROPERTY, INTERNAL, HIDDEN, SHORTCUT, WEAK, DEFAULT = PROPERTY }; - -class Node { -public: - explicit Node(uint64_t id, uint64_t index, CString *name, NodeType type, size_t size, uint64_t traceId, - Address address, bool isLive = true) - : id_(id), - index_(index), - name_(name), - type_(type), - size_(size), - traceId_(traceId), - address_(address), - isLive_(isLive) - { - } - uint64_t GetId() const - { - return id_; - } - void SetIndex(uint64_t index) - { - index_ = index; - } - uint64_t GetIndex() const - { - return index_; - } - - const CString *GetName() const - { - return name_; - } - NodeType GetType() const - { - return type_; - } - size_t GetSelfSize() const - { - return size_; - } - size_t GetEdgeCount() const - { - return edgeCount_; - } - void IncEdgeCount() - { - edgeCount_++; - } - uint64_t GetStackTraceId() const - { - return traceId_; - } - Address GetAddress() const - { - return address_; - } - bool IsLive() const - { - return isLive_; - } - void SetLive(bool isLive) - { - isLive_ = isLive; - } - static Node *NewNode(const Heap *heap, size_t id, size_t index, CString *name, NodeType type, size_t size, - TaggedObject *entry, bool isLive = true); - template - static Address NewAddress(T *addr) - { - return reinterpret_cast
(addr); - } - static constexpr int NODE_FIELD_COUNT = 7; - ~Node() = default; - - DEFAULT_MOVE_SEMANTIC(Node); - DEFAULT_COPY_SEMANTIC(Node); - -private: - uint64_t id_ {0}; // Range from 1 - uint64_t index_ {0}; - CString *name_ {nullptr}; - NodeType type_ {NodeType::INVALID}; - size_t size_ {0}; - size_t edgeCount_ {0}; - uint64_t traceId_ {0}; - Address address_ {0x0}; - bool isLive_ {true}; -}; - -class Edge { -public: - explicit Edge(uint64_t id, EdgeType type, Node *from, Node *to, CString *name) - : id_(id), edgeType_(type), from_(from), to_(to), name_(name) - { - } - uint64_t GetId() const - { - return id_; - } - EdgeType GetType() const - { - return edgeType_; - } - const Node *GetFrom() const - { - return from_; - } - const Node *GetTo() const - { - return to_; - } - const CString *GetName() const - { - return name_; - } - void SetName(CString *name) - { - name_ = name; - } - void UpdateFrom(Node *node) - { - from_ = node; - } - void UpdateTo(Node *node) - { - to_ = node; - } - static Edge *NewEdge(const Heap *heap, uint64_t id, EdgeType type, Node *from, Node *to, CString *name); - static constexpr int EDGE_FIELD_COUNT = 3; - ~Edge() = default; - - DEFAULT_MOVE_SEMANTIC(Edge); - DEFAULT_COPY_SEMANTIC(Edge); - -private: - uint64_t id_ {-1ULL}; - EdgeType edgeType_ {EdgeType::DEFAULT}; - Node *from_ {nullptr}; - Node *to_ {nullptr}; - CString *name_ {nullptr}; -}; - -class TimeStamp { -public: - explicit TimeStamp(int sequenceId) : lastSequenceId_(sequenceId), timeStampUs_(TimeStamp::Now()) {} - ~TimeStamp() = default; - - DEFAULT_MOVE_SEMANTIC(TimeStamp); - DEFAULT_COPY_SEMANTIC(TimeStamp); - - int GetLastSequenceId() const - { - return lastSequenceId_; - } - - int64_t GetTimeStamp() const - { - return timeStampUs_; - } - -private: - static int64_t Now() - { - struct timeval tv = {0, 0}; - gettimeofday(&tv, nullptr); - const int THOUSAND = 1000; - return tv.tv_usec + tv.tv_sec * THOUSAND * THOUSAND; - } - - int lastSequenceId_ {0}; - int64_t timeStampUs_ {0}; -}; - -class HeapEntryMap { -public: - HeapEntryMap() = default; - ~HeapEntryMap() = default; - NO_MOVE_SEMANTIC(HeapEntryMap); - NO_COPY_SEMANTIC(HeapEntryMap); - Node *FindOrInsertNode(Node *node); - Node *FindAndEraseNode(Address addr); - Node *FindEntry(Address addr); - size_t GetCapcity() const - { - return nodesMap_.size(); - } - size_t GetEntryCount() const - { - return nodeEntryCount_; - } - void InsertEntry(Node *node); - -private: - size_t nodeEntryCount_ {0}; - CUnorderedMap nodesMap_ {}; -}; - -class HeapSnapShot { -public: - static constexpr int SEQ_STEP = 2; - NO_MOVE_SEMANTIC(HeapSnapShot); - NO_COPY_SEMANTIC(HeapSnapShot); - explicit HeapSnapShot(JSThread *thread, const Heap *heap, const bool isVmMode) - : stringTable_(heap), thread_(thread), heap_(heap), isVmMode_(isVmMode) - { - } - ~HeapSnapShot(); - bool BuildUp(JSThread *thread); - bool Verify(); - - void PrepareSnapShot(); - void UpdateNode(); - void AddNode(uintptr_t address); - void MoveNode(uintptr_t address, uintptr_t forward_address); - void RecordSampleTime(); - bool FinishSnapShot(); - - const CVector &GetTimeStamps() const - { - return timeStamps_; - } - - size_t GetNodeCount() const - { - return nodeCount_; - } - size_t GetEdgeCount() const - { - return edgeCount_; - } - size_t GetTotalNodeSize() const - { - return totalNodesSize_; - } - void AccumulateNodeSize(size_t size) - { - totalNodesSize_ += size; - } - void DecreaseNodeSize(size_t size) - { - totalNodesSize_ -= size; - } - CString *GenerateNodeName(JSThread *thread, const JSHandle &entry); - NodeType GenerateNodeType(TaggedObject *entry); - const CList *GetNodes() const - { - return &nodes_; - } - const CVector *GetEdges() const - { - return &edges_; - } - const StringHashMap *GetEcmaStringTable() const - { - return &stringTable_; - } - - CString *GetString(const CString &as); - - bool IsInVmMode() const - { - return isVmMode_; - } - -private: - void FillNodes(JSThread *thread); - Node *GenerateNode(JSThread *thread, JSTaggedValue entry, int sequenceId = -1); - Node *GenerateStringNode(JSTaggedValue entry, int sequenceId); - void FillEdges(JSThread *thread); - void BridgeAllReferences(); - CString *GenerateEdgeName(TaggedObject *from, TaggedObject *to); - - Node *InsertNodeUnique(Node *node); - void EraseNodeUnique(Node *node); - Edge *InsertEdgeUnique(Edge *edge); - void AddSyntheticRoot(JSThread *thread); - Node *InsertNodeAt(size_t pos, Node *node); - Edge *InsertEdgeAt(size_t pos, Edge *edge); - - StringHashMap stringTable_; - CList nodes_ {}; - CVector edges_ {}; - CVector timeStamps_ {}; - std::atomic_int sequenceId_ {1}; // 1 Reversed for SyntheticRoot - int nodeCount_ {0}; - int edgeCount_ {0}; - int totalNodesSize_ {0}; - HeapEntryMap entryMap_; - panda::ecmascript::HeapRootVisitor rootVisitor_; - JSThread *thread_; - const Heap *heap_; - bool isVmMode_ {true}; -}; - -class EntryVisitor { -public: - NO_MOVE_SEMANTIC(EntryVisitor); - NO_COPY_SEMANTIC(EntryVisitor); - explicit EntryVisitor() = default; - ~EntryVisitor() = default; - static CString ConvertKey(JSTaggedValue key); -}; - -enum class FrontType { - HIDDEN, /* kHidden */ - ARRAY, /* kArray */ - STRING, /* kString */ - OBJECT, /* kObject */ - CODE, /* kCode */ - CLOSURE, /* kClosure */ - REGEXP, /* kRegExp */ - HEAPNUMBER, /* kHeapNumber */ - NATIVE, /* kNative */ - SYNTHETIC, /* kSynthetic */ - CONSSTRING, /* kConsString */ - SLICEDSTRING, /* kSlicedString */ - SYMBOL, /* kSymbol */ - BIGINT, /* kBigInt */ - DEFAULT = NATIVE, /* kDefault */ -}; - -class NodeTypeConverter { -public: - explicit NodeTypeConverter() = default; - ~NodeTypeConverter() = default; - NO_MOVE_SEMANTIC(NodeTypeConverter); - NO_COPY_SEMANTIC(NodeTypeConverter); - /* - * For Front-End to Show Statistics Correctly - */ - static FrontType Convert(NodeType type); -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_HPROF_HEAP_SNAPSHOT_H diff --git a/runtime/hprof/heap_snapshot_json_serializer.cpp b/runtime/hprof/heap_snapshot_json_serializer.cpp deleted file mode 100644 index a811dd6278cffeae2df54971326e0f0cc78c0f85..0000000000000000000000000000000000000000 --- a/runtime/hprof/heap_snapshot_json_serializer.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/hprof/heap_snapshot_json_serializer.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" -#include "plugins/ecmascript/runtime/hprof/heap_snapshot.h" -#include "plugins/ecmascript/runtime/hprof/string_hashmap.h" - -namespace panda::ecmascript { -bool HeapSnapShotJSONSerializer::Serialize(HeapSnapShot *snapShot, const CString &fileName) -{ - // Serialize Node/Edge/String-Table - LOG(ERROR, RUNTIME) << "HeapSnapShotJSONSerializer::Serialize begin"; - snapShot_ = snapShot; - ASSERT(snapShot_->GetNodes() != nullptr && snapShot_->GetEdges() != nullptr && - snapShot_->GetEcmaStringTable() != nullptr); - stringBuffer_.str(""); // Clear Buffer - - SerializeSnapShotHeader(); // 1. - SerializeNodes(); // 2. - SerializeEdges(); // 3. - SerializeTraceFunctionInfo(); // 4. - SerializeTraceTree(); // 5. - SerializeSamples(); // 6. - SerializeLocations(); // 7. - SerializeStringTable(); // 8. - SerializerSnapShotClosure(); // 9. - - WriteJSON(fileName); // 10. - LOG(ERROR, RUNTIME) << "HeapSnapShotJSONSerializer::Serialize exit"; - return true; -} - -void HeapSnapShotJSONSerializer::SerializeSnapShotHeader() -{ - stringBuffer_ << "{\"snapshot\":\n"; // 1. - stringBuffer_ << "{\"meta\":\n"; // 2. - // NOLINTNEXTLINE(modernize-raw-string-literal) - stringBuffer_ << "{\"node_fields\":[\"type\",\"name\",\"id\",\"self_size\",\"edge_count\",\"trace_node_id\","; - stringBuffer_ << "\"detachedness\"],\n"; // 3. - // NOLINTNEXTLINE(modernize-raw-string-literal) - stringBuffer_ << "\"node_types\":[[\"hidden\",\"array\",\"string\",\"object\",\"code\",\"closure\",\"regexp\","; - // NOLINTNEXTLINE(modernize-raw-string-literal) - stringBuffer_ << "\"number\",\"native\",\"synthetic\",\"concatenated string\",\"slicedstring\",\"symbol\","; - // NOLINTNEXTLINE(modernize-raw-string-literal) - stringBuffer_ << "\"bigint\"],\"string\",\"number\",\"number\",\"number\",\"number\",\"number\"],\n"; // 4. - // NOLINTNEXTLINE(modernize-raw-string-literal) - stringBuffer_ << "\"edge_fields\":[\"type\",\"name_or_index\",\"to_node\"],\n"; // 5. - // NOLINTNEXTLINE(modernize-raw-string-literal) - stringBuffer_ << "\"edge_types\":[[\"context\",\"element\",\"property\",\"internal\",\"hidden\",\"shortcut\","; - // NOLINTNEXTLINE(modernize-raw-string-literal) - stringBuffer_ << "\"weak\"],\"string_or_number\",\"node\"],\n"; // 6. - // NOLINTNEXTLINE(modernize-raw-string-literal) - stringBuffer_ << "\"trace_function_info_fields\":[\"function_id\",\"name\",\"script_name\",\"script_id\","; - // NOLINTNEXTLINE(modernize-raw-string-literal) - stringBuffer_ << "\"line\",\"column\"],\n"; // 7. - // NOLINTNEXTLINE(modernize-raw-string-literal) - stringBuffer_ << "\"trace_node_fields\":[\"id\",\"function_info_index\",\"count\",\"size\",\"children\"],\n"; - // NOLINTNEXTLINE(modernize-raw-string-literal) - stringBuffer_ << "\"sample_fields\":[\"timestamp_us\",\"last_assigned_id\"],\n"; // 9. - // NOLINTNEXTLINE(modernize-raw-string-literal) - stringBuffer_ << "\"location_fields\":[\"object_index\",\"script_id\",\"line\",\"column\"]},\n"; // 10. - stringBuffer_ << "\"node_count\":" << snapShot_->GetNodeCount() << ",\n"; // 11. - stringBuffer_ << "\"edge_count\":" << snapShot_->GetEdgeCount() << ",\n"; // 12. - stringBuffer_ << "\"trace_function_count\":" - << "0\n"; // 13. - stringBuffer_ << "},\n"; // 14. -} - -void HeapSnapShotJSONSerializer::SerializeNodes() -{ - const CList *nodes = snapShot_->GetNodes(); - const StringHashMap *stringTable = snapShot_->GetEcmaStringTable(); - ASSERT(nodes != nullptr); - stringBuffer_ << "\"nodes\":["; // Section Header - size_t i = 0; - for (auto *node : *nodes) { - if (i > 0) { - stringBuffer_ << ","; // add comma except first line - } - stringBuffer_ << static_cast(NodeTypeConverter::Convert(node->GetType())) << ","; // 1. - stringBuffer_ << stringTable->GetStringId(node->GetName()) << ","; // 2. - stringBuffer_ << node->GetId() << ","; // 3. - stringBuffer_ << node->GetSelfSize() << ","; // 4. - stringBuffer_ << node->GetEdgeCount() << ","; // 5. - stringBuffer_ << node->GetStackTraceId() << ","; // 6. - if (i == nodes->size() - 1) { // add comma at last the line - stringBuffer_ << "0" - << "],\n"; // 7. detachedness default - } else { - stringBuffer_ << "0\n"; // 7. - } - i++; - } -} - -void HeapSnapShotJSONSerializer::SerializeEdges() -{ - const CVector *edges = snapShot_->GetEdges(); - const StringHashMap *stringTable = snapShot_->GetEcmaStringTable(); - ASSERT(edges != nullptr); - stringBuffer_ << "\"edges\":["; - size_t i = 0; - for (auto *edge : *edges) { - if (i > 0) { // add comma except the first line - stringBuffer_ << ","; - } - stringBuffer_ << static_cast(edge->GetType()) << ","; // 1. - stringBuffer_ << stringTable->GetStringId(edge->GetName()) << ","; // 2. Use StringId - - if (i == edges->size() - 1) { // add comma at last the line - stringBuffer_ << edge->GetTo()->GetIndex() * Node::NODE_FIELD_COUNT << "],\n"; // 3. - } else { - stringBuffer_ << edge->GetTo()->GetIndex() * Node::NODE_FIELD_COUNT << "\n"; // 3. - } - i++; - } -} - -void HeapSnapShotJSONSerializer::SerializeTraceFunctionInfo() -{ - stringBuffer_ << "\"trace_function_infos\":[],\n"; // Empty -} - -void HeapSnapShotJSONSerializer::SerializeTraceTree() -{ - stringBuffer_ << "\"trace_tree\":[],\n"; // Empty -} - -void HeapSnapShotJSONSerializer::SerializeSamples() -{ - stringBuffer_ << "\"samples\":["; - const CVector &timeStamps = snapShot_->GetTimeStamps(); - if (!timeStamps.empty()) { - auto firstTimeStamp = timeStamps[0]; - bool isFirst = true; - for (auto timeStamp : timeStamps) { - if (!isFirst) { - stringBuffer_ << "\n, "; - } else { - isFirst = false; - } - stringBuffer_ << timeStamp.GetTimeStamp() - firstTimeStamp.GetTimeStamp() << ", "; - stringBuffer_ << timeStamp.GetLastSequenceId(); - } - } - stringBuffer_ << "],\n"; -} - -void HeapSnapShotJSONSerializer::SerializeLocations() -{ - stringBuffer_ << "\"locations\":[],\n"; -} - -void HeapSnapShotJSONSerializer::SerializeStringTable() -{ - const StringHashMap *stringTable = snapShot_->GetEcmaStringTable(); - ASSERT(stringTable != nullptr); - stringBuffer_ << "\"strings\":[\"\",\n"; - stringBuffer_ << "\"\",\n"; - stringBuffer_ << "\"GC roots\",\n"; - // StringId Range from 3 - size_t capcity = stringTable->GetCapcity(); - size_t i = 0; - for (auto key : stringTable->GetOrderedKeyStorage()) { - if (i == capcity - 1) { - stringBuffer_ << "\"" << *(stringTable->GetStringByKey(key)) << "\"\n"; // No Comma for the last line - } else { - stringBuffer_ << "\"" << *(stringTable->GetStringByKey(key)) << "\",\n"; - } - i++; - } - stringBuffer_ << "]\n"; -} - -void HeapSnapShotJSONSerializer::SerializerSnapShotClosure() -{ - stringBuffer_ << "}\n"; -} - -void HeapSnapShotJSONSerializer::WriteJSON(const CString &fileName) -{ - std::string fName(fileName); - LOG(ERROR, RUNTIME) << "HeapSnapShotJSONSerializer::WriteJSON" << fName; - outputStream_.open(fName, std::ios::out); - if (!outputStream_.good()) { - LOG_ECMA(ERROR) << "open file failed"; - return; - } - outputStream_ << stringBuffer_.str(); - outputStream_.close(); - outputStream_.clear(); // Make sure the next open operation success -} -} // namespace panda::ecmascript diff --git a/runtime/hprof/heap_snapshot_json_serializer.h b/runtime/hprof/heap_snapshot_json_serializer.h deleted file mode 100644 index 84ebf89d31079752b1eceb41686b5ea16d7a5999..0000000000000000000000000000000000000000 --- a/runtime/hprof/heap_snapshot_json_serializer.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_HPROF_HEAP_SNAPSHOT_SERIALIZER_H -#define ECMASCRIPT_HPROF_HEAP_SNAPSHOT_SERIALIZER_H - -#include -#include - -#include "plugins/ecmascript/runtime/mem/c_string.h" -#include "os/mem.h" - -namespace panda::ecmascript { -using fstream = std::fstream; -using stringstream = std::stringstream; - -class HeapSnapShot; - -class HeapSnapShotJSONSerializer { -public: - explicit HeapSnapShotJSONSerializer() = default; - ~HeapSnapShotJSONSerializer() = default; - NO_MOVE_SEMANTIC(HeapSnapShotJSONSerializer); - NO_COPY_SEMANTIC(HeapSnapShotJSONSerializer); - bool Serialize(HeapSnapShot *snapShot, const CString &fileName); - -private: - void SerializeSnapShotHeader(); - void SerializeNodes(); - void SerializeEdges(); - void SerializeTraceFunctionInfo(); - void SerializeTraceTree(); - void SerializeSamples(); - void SerializeLocations(); - void SerializeStringTable(); - void SerializerSnapShotClosure(); - - void WriteJSON(const CString &fileName); - fstream outputStream_; - HeapSnapShot *snapShot_ {nullptr}; - stringstream stringBuffer_; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_HPROF_HEAP_SNAPSHOT_SERIALIZER_H diff --git a/runtime/hprof/heap_tracker.cpp b/runtime/hprof/heap_tracker.cpp deleted file mode 100644 index c15fd68e9a46ad0315e8d5c6b95d821fc87b2fe1..0000000000000000000000000000000000000000 --- a/runtime/hprof/heap_tracker.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/hprof/heap_tracker.h" -#include "plugins/ecmascript/runtime/hprof/heap_snapshot.h" -#include "plugins/ecmascript/runtime/mem/space.h" - -namespace panda::ecmascript { -static constexpr int32_t MILLI_TO_MICRO = 1000; - -void HeapTrackerSample::Run() -{ - while (!isInterrupt_) { - snapShot_->RecordSampleTime(); - usleep(timeInterval_ * MILLI_TO_MICRO); - } -} - -void HeapTracker::AllocationEvent(uintptr_t address) -{ - if (snapShot_ != nullptr) { - snapShot_->AddNode(address); - } -} - -void HeapTracker::MoveEvent(uintptr_t address, uintptr_t forward_address) -{ - if (snapShot_ != nullptr) { - snapShot_->MoveNode(address, forward_address); - } -} -} // namespace panda::ecmascript diff --git a/runtime/hprof/heap_tracker.h b/runtime/hprof/heap_tracker.h deleted file mode 100644 index f0d98e1e35ceb1ca0a524a67a70c69f01ed2c588..0000000000000000000000000000000000000000 --- a/runtime/hprof/heap_tracker.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_HPROF_HEAP_TRACKER_H -#define ECMASCRIPT_HPROF_HEAP_TRACKER_H - -#include -#include -#include - -#include "libpandabase/macros.h" - -namespace panda::ecmascript { -class HeapSnapShot; - -class HeapTrackerSample { -public: - explicit HeapTrackerSample(HeapSnapShot *snapShot, double timeInterval) - : timeInterval_(timeInterval), snapShot_(snapShot) - { - } - - ~HeapTrackerSample() - { - isInterrupt_ = true; - } - - void Start() - { - isInterrupt_ = false; - thread_ = std::thread(&HeapTrackerSample::Run, this); - } - - void Stop() - { - isInterrupt_ = true; - if (thread_.joinable()) { - thread_.join(); - } - } - - void Run(); - - NO_COPY_SEMANTIC(HeapTrackerSample); - NO_MOVE_SEMANTIC(HeapTrackerSample); - -private: - std::thread thread_; - std::atomic_bool isInterrupt_ = true; - double timeInterval_ = 0; - HeapSnapShot *snapShot_; -}; - -class HeapTracker { -public: - HeapTracker(HeapSnapShot *snapShot, double timeInterval) : snapShot_(snapShot), sample_(snapShot, timeInterval) {} - ~HeapTracker() = default; - - void StartTracing() - { - sample_.Start(); - } - - void StopTracing() - { - sample_.Stop(); - } - - void AllocationEvent(uintptr_t address); - void MoveEvent(uintptr_t address, uintptr_t forward_address); - - NO_COPY_SEMANTIC(HeapTracker); - NO_MOVE_SEMANTIC(HeapTracker); - -private: - HeapSnapShot *snapShot_; - HeapTrackerSample sample_; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_HPROF_HEAP_TRACKER_H diff --git a/runtime/hprof/string_hashmap.cpp b/runtime/hprof/string_hashmap.cpp deleted file mode 100644 index 43c0218ee50a3eabb830ab11323b4a412f475982..0000000000000000000000000000000000000000 --- a/runtime/hprof/string_hashmap.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/hprof/string_hashmap.h" - -namespace panda::ecmascript { -CString *StringHashMap::FindOrInsertString(CString *string) -{ - StringKey key = GenerateStringKey(string); - auto it = hashmap_.find(key); - if (it != hashmap_.end()) { - return it->second; - } - index_++; - hashmap_.insert(std::make_pair(key, string)); - orderedKey_.emplace_back(key); - indexMap_.insert(std::make_pair(key, index_)); - return string; -} - -StringId StringHashMap::GetStringId(const CString *string) const -{ - auto it = indexMap_.find(GenerateStringKey(string)); - return it != indexMap_.end() ? it->second : 1; // "" -} - -CString *StringHashMap::GetStringByKey(StringKey key) const -{ - auto it = hashmap_.find(key); - if (it != hashmap_.end()) { - return FormatString(it->second); - } - return nullptr; -} - -CString *StringHashMap::FormatString(CString *string) const -{ - // remove "\"" | "\r\n" | "\\" | "\t" | "\f" - int length = string->length(); - char *charSeq = const_cast(string->c_str()); - for (int i = 0; i < length; i++) { - if (charSeq[i] == '\"') { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - charSeq[i] = '`'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - } else if (charSeq[i] == '\r') { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - charSeq[i] = '`'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - } else if (charSeq[i] == '\n') { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - charSeq[i] = '`'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - } else if (charSeq[i] == '\\') { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - charSeq[i] = '`'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - } else if (charSeq[i] == '\t') { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - charSeq[i] = '`'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - } else if (charSeq[i] == '\f') { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - charSeq[i] = '`'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - } else if (charSeq[i] < ' ') { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - // ctrl chars 0~31 - charSeq[i] = '`'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - } - } - *string = charSeq; - return string; -} - -StringKey StringHashMap::GenerateStringKey(const CString *string) const -{ - return std::hash {}(std::string(*string)); -} - -CString *StringHashMap::GetString(CString as) -{ - auto *tempString = const_cast(heap_->GetRegionFactory())->New(std::move(as)); - CString *oldString = FindOrInsertString(tempString); - if (tempString != oldString) { - const_cast(heap_->GetRegionFactory())->Delete(tempString); - return oldString; - } - return tempString; -} - -void StringHashMap::Clear() -{ - for (auto it : hashmap_) { - if (it.second != nullptr) { - const_cast(heap_->GetRegionFactory())->Delete(it.second); - } - } -} -} // namespace panda::ecmascript diff --git a/runtime/hprof/string_hashmap.h b/runtime/hprof/string_hashmap.h deleted file mode 100644 index 776a750d67213c7ffc848ee25d7ced41423e6c52..0000000000000000000000000000000000000000 --- a/runtime/hprof/string_hashmap.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_HPROF_STRING_HASHMAP_H -#define ECMASCRIPT_HPROF_STRING_HASHMAP_H - -#include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" -#include "plugins/ecmascript/runtime/mem/c_string.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "os/mem.h" - -namespace panda::ecmascript { -using StringKey = uint64_t; -using StringId = uint64_t; - -// An Implementation for Native StringTable without Auto Mem-Management -// To make sure when using String, it still stays where it was. -class StringHashMap { -public: - explicit StringHashMap(const Heap *heap) : heap_(heap) - { - ASSERT(heap_ != nullptr); - } - ~StringHashMap() - { - Clear(); - } - NO_MOVE_SEMANTIC(StringHashMap); - NO_COPY_SEMANTIC(StringHashMap); - /* - * The ID is the seat number in JSON file Range from 0~string_table_.size() - */ - StringId GetStringId(const CString *string) const; - /* - * Get all keys sorted by insert order - */ - const CVector &GetOrderedKeyStorage() const - { - return orderedKey_; - } - /* - * Get string by its hash key - */ - CString *GetStringByKey(StringKey key) const; - size_t GetCapcity() const - { - ASSERT(orderedKey_.size() == hashmap_.size()); - return orderedKey_.size(); - } - /* - * For external call to use this StringTable - */ - CString *GetString(CString as); - -private: - StringKey GenerateStringKey(const CString *string) const; - CString *FindOrInsertString(CString *string); - CString *FormatString(CString *string) const; - /* - * Free all memory - */ - void Clear(); - const Heap *heap_; - CVector orderedKey_; // Used for Serialize Order - size_t index_ {2}; // 2: Offset the String-Table Header - CUnorderedMap indexMap_; - CUnorderedMap hashmap_; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_HPROF_STRING_HASHMAP_H diff --git a/runtime/internal_call_params.h b/runtime/internal_call_params.h index 6ba39e8a582b3995cadbfde721d8ece19e89354a..d707522dec3b6e2b8902fd1791ab93685914fbaf 100644 --- a/runtime/internal_call_params.h +++ b/runtime/internal_call_params.h @@ -20,7 +20,6 @@ #include "plugins/ecmascript/runtime/js_tagged_value.h" #include "plugins/ecmascript/runtime/js_handle.h" #include "plugins/ecmascript/runtime/js_function.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" namespace panda::ecmascript { class InternalCallParams { @@ -222,7 +221,7 @@ private: } std::array fixed_data_ {}; - CVector variable_data_ {}; + PandaVector variable_data_ {}; uint32_t fixed_length_ {0}; uint32_t variable_length_ {0}; bool variable_mode_ {false}; diff --git a/runtime/interpreter/ecma-interpreter-inl.h b/runtime/interpreter/ecma-interpreter-inl.h index 6c175a80f8a51d39b780cfbba6e2ce357bf790e0..5273e0060480892cde5aa130007dbe6e6074a340 100644 --- a/runtime/interpreter/ecma-interpreter-inl.h +++ b/runtime/interpreter/ecma-interpreter-inl.h @@ -750,7 +750,7 @@ public: auto string_id = this->GetInst().template GetId(); auto prop = GetConstantPool(this->GetJSThread())->GetObjectFromCache(string_id.AsIndex()); LOG_INST() << "throwconstassignment " - << "stringId:" << ConvertToString(EcmaString::Cast(prop.GetHeapObject())); + << "stringId:" << ConvertToPandaString(EcmaString::Cast(prop.GetHeapObject())); auto thread = JSThread::Cast(this->GetThread()); SlowRuntimeStub::ThrowConstAssignment(thread, prop); @@ -1433,7 +1433,7 @@ public: auto string_id = this->GetInst().template GetId(); auto prop = GetConstantPool(this->GetJSThread())->GetObjectFromCache(string_id.AsIndex()); LOG_INST() << "intrinsic::throwundefinedifhole " - << "stringId:" << ConvertToString(EcmaString::Cast(prop.GetHeapObject())); + << "stringId:" << ConvertToPandaString(EcmaString::Cast(prop.GetHeapObject())); if (!GetAccAsTaggedValue().IsHole()) { this->template MoveToNextInst(); diff --git a/runtime/interpreter/fast_runtime_stub-inl.h b/runtime/interpreter/fast_runtime_stub-inl.h index b008c72b6e5b5b900032b82b1c9b21757b846fb8..c3105ab56bb31d4584d44b58433b50c863ccb2c4 100644 --- a/runtime/interpreter/fast_runtime_stub-inl.h +++ b/runtime/interpreter/fast_runtime_stub-inl.h @@ -797,7 +797,6 @@ JSTaggedValue FastRuntimeStub::GetElement(JSTaggedValue receiver, uint32_t index JSTaggedValue FastRuntimeStub::GetElementWithArray(JSTaggedValue receiver, uint32_t index) { - DISALLOW_GARBAGE_COLLECTION; JSTaggedValue holder = receiver; while (true) { JSTaggedValue val = FindOwnElement(JSObject::Cast(holder), index); diff --git a/runtime/interpreter/slow_runtime_helper.cpp b/runtime/interpreter/slow_runtime_helper.cpp index 81e4af0597ebf130d750a90f41eead00123904de..ce82a7dcd6d6a88beff394191f2f7c5ef009774e 100644 --- a/runtime/interpreter/slow_runtime_helper.cpp +++ b/runtime/interpreter/slow_runtime_helper.cpp @@ -21,7 +21,6 @@ #include "plugins/ecmascript/runtime/js_generator_object.h" #include "plugins/ecmascript/runtime/js_invoker.h" #include "plugins/ecmascript/runtime/js_tagged_value.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "plugins/ecmascript/runtime/tagged_array-inl.h" namespace panda::ecmascript { @@ -118,7 +117,7 @@ JSTaggedValue ConstructGeneric(JSThread *thread, JSHandle ctor, JSHa } uint32_t preArgsSize = preArgs->IsUndefined() ? 0 : JSHandle::Cast(preArgs)->GetLength(); const uint32_t size = preArgsSize + argsCount; - CVector values; + PandaVector values; values.reserve(size); JSMethod *method = ctor->GetCallTarget(); diff --git a/runtime/jobs/micro_job_queue.h b/runtime/jobs/micro_job_queue.h index d1cde4990c1d67178042d39aa73b584fa9a687f7..bb519fb6f0efe199a2adc0079dcae5cbd4b498e6 100644 --- a/runtime/jobs/micro_job_queue.h +++ b/runtime/jobs/micro_job_queue.h @@ -21,7 +21,6 @@ #include "plugins/ecmascript/runtime/jobs/pending_job.h" #include "plugins/ecmascript/runtime/js_handle.h" #include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "plugins/ecmascript/runtime/object_factory.h" #include "plugins/ecmascript/runtime/record.h" #include "plugins/ecmascript/runtime/tagged_array.h" diff --git a/runtime/jobs/pending_job.h b/runtime/jobs/pending_job.h index a29ad55b8658d1f415057784dd9bfb4fadf1631e..8907b3278d6f7b775578ab0823a2bac453b00579 100644 --- a/runtime/jobs/pending_job.h +++ b/runtime/jobs/pending_job.h @@ -23,7 +23,6 @@ #include "plugins/ecmascript/runtime/js_handle.h" #include "plugins/ecmascript/runtime/object_factory.h" #include "plugins/ecmascript/runtime/tagged_array.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" namespace panda::ecmascript::job { class PendingJob final : public Record { diff --git a/runtime/js_collator.cpp b/runtime/js_collator.cpp index 571c66a03dc1b14c5d2d1d345b505e0cb7e60685..a39d91e6d14b3e24485af3c189e703b2ca795036 100644 --- a/runtime/js_collator.cpp +++ b/runtime/js_collator.cpp @@ -18,11 +18,11 @@ #include "unicode/udata.h" #include "plugins/ecmascript/runtime/global_env.h" -#include "plugins/ecmascript/runtime/mem/c_string.h" +#include "plugins/ecmascript/runtime/mem/ecma_string.h" namespace panda::ecmascript { // NOLINTNEXTLINE (readability-identifier-naming, fuchsia-statically-constructed-objects) -const CString JSCollator::uIcuDataColl = U_ICUDATA_NAME U_TREE_SEPARATOR_STRING "coll"; +const PandaString JSCollator::uIcuDataColl = U_ICUDATA_NAME U_TREE_SEPARATOR_STRING "coll"; // NOLINTNEXTLINE(fuchsia-statically-constructed-objects) const std::map JSCollator::caseFirstMap = { {"upper", CaseFirstOption::UPPER}, {"lower", CaseFirstOption::LOWER}, {"false", CaseFirstOption::FALSE_OPTION}}; @@ -419,7 +419,7 @@ JSHandle JSCollator::ResolvedOptions(JSThread *thread, const JSHandle< icu::UnicodeString EcmaStringToUString(const JSHandle &string) { - std::string stdString(ConvertToString(*string, StringConvertedUsage::LOGICOPERATION)); + std::string stdString(ConvertToPandaString(*string, StringConvertedUsage::LOGICOPERATION)); icu::StringPiece sp(stdString); icu::UnicodeString uString = icu::UnicodeString::fromUTF8(sp); return uString; diff --git a/runtime/js_collator.h b/runtime/js_collator.h index f307bbfdff7651bb6ba27de1cb8f8c1e858944ba..ad2fe653112a2db3b2bd069a511d6e8d622ffb77 100644 --- a/runtime/js_collator.h +++ b/runtime/js_collator.h @@ -28,7 +28,7 @@ enum class SensitivityOption : uint8_t { BASE = 0x01, ACCENT, CASE, VARIANT, UND class JSCollator : public JSObject { public: // NOLINTNEXTLINE (readability-identifier-naming, fuchsia-statically-constructed-objects) - static const CString uIcuDataColl; + static const PandaString uIcuDataColl; static const std::map caseFirstMap; diff --git a/runtime/js_date.cpp b/runtime/js_date.cpp index 957c31d27535dd71c83fb8518e1212b2648cd129..ce0204fd2068c590af987df63e96d0acd180c80f 100644 --- a/runtime/js_date.cpp +++ b/runtime/js_date.cpp @@ -167,7 +167,7 @@ double JSDate::UTCTime(double timeMs) const } // static -int JSDate::GetSignedNumFromString(const CString &str, int len, int *index) +int JSDate::GetSignedNumFromString(const PandaString &str, int len, int *index) { int res = 0; GetNumFromString(str, len, index, &res); @@ -178,7 +178,7 @@ int JSDate::GetSignedNumFromString(const CString &str, int len, int *index) } // static -bool JSDate::GetNumFromString(const CString &str, int len, int *index, int *num) +bool JSDate::GetNumFromString(const PandaString &str, int len, int *index, int *num) { int indexStr = *index; char oneByte = 0; @@ -223,7 +223,7 @@ int64_t JSDate::GetLocalOffsetInMin(const JSThread *thread, int64_t timeMs, bool } // static -JSTaggedValue JSDate::LocalParseStringToMs(const CString &str) +JSTaggedValue JSDate::LocalParseStringToMs(const PandaString &str) { int year = 0; int month = 0; @@ -235,17 +235,17 @@ JSTaggedValue JSDate::LocalParseStringToMs(const CString &str) int index = 0; int len = str.length(); bool isLocal = false; - CString::size_type indexGmt; - CString::size_type indexPlus = CString::npos; - std::array monthName = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + PandaString::size_type indexGmt; + PandaString::size_type indexPlus = PandaString::npos; + std::array monthName = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; int localTime = 0; int localHours = 0; int localMinutes = 0; int64_t localMs = 0; - CString::size_type localSpace; + PandaString::size_type localSpace; localSpace = str.find(' ', index); - CString strMonth = str.substr(localSpace + 1, LENGTH_MONTH_NAME); + PandaString strMonth = str.substr(localSpace + 1, LENGTH_MONTH_NAME); for (int i = 0; i < MOUTH_PER_YEAR; i++) { if (strMonth == monthName[i]) { month = i; @@ -256,7 +256,7 @@ JSTaggedValue JSDate::LocalParseStringToMs(const CString &str) GetNumFromString(str, len, &index, &date); GetNumFromString(str, len, &index, &year); indexGmt = str.find("GMT", index); - if (indexGmt == CString::npos) { + if (indexGmt == PandaString::npos) { GetNumFromString(str, len, &index, &hours); GetNumFromString(str, len, &index, &minutes); GetNumFromString(str, len, &index, &seconds); @@ -272,7 +272,7 @@ JSTaggedValue JSDate::LocalParseStringToMs(const CString &str) localHours = localTime / HUNDRED; localMinutes = localTime % HUNDRED; localMs = static_cast(MakeTime(localHours, localMinutes, 0, 0)); - if (indexPlus != CString::npos) { + if (indexPlus != PandaString::npos) { localMs = -localMs; } } @@ -291,7 +291,7 @@ JSTaggedValue JSDate::LocalParseStringToMs(const CString &str) } // static -JSTaggedValue JSDate::UtcParseStringToMs(const CString &str) +JSTaggedValue JSDate::UtcParseStringToMs(const PandaString &str) { int year = 0; int month = 0; @@ -302,17 +302,17 @@ JSTaggedValue JSDate::UtcParseStringToMs(const CString &str) int ms = 0; int index = 0; int len = str.length(); - CString::size_type indexGmt; - CString::size_type indexPlus = CString::npos; + PandaString::size_type indexGmt; + PandaString::size_type indexPlus = PandaString::npos; int localTime = 0; int localHours = 0; int localMinutes = 0; int64_t localMs = 0; bool isLocal = false; - std::array monthName = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + std::array monthName = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; GetNumFromString(str, len, &index, &date); - CString strMonth = str.substr(index + 1, LENGTH_MONTH_NAME); + PandaString strMonth = str.substr(index + 1, LENGTH_MONTH_NAME); for (int i = 0; i < MOUTH_PER_YEAR; i++) { if (strMonth == monthName[i]) { month = i; @@ -322,7 +322,7 @@ JSTaggedValue JSDate::UtcParseStringToMs(const CString &str) index += (LENGTH_MONTH_NAME + 1); GetNumFromString(str, len, &index, &year); indexGmt = str.find("GMT", index); - if (indexGmt == CString::npos) { + if (indexGmt == PandaString::npos) { GetNumFromString(str, len, &index, &hours); GetNumFromString(str, len, &index, &minutes); GetNumFromString(str, len, &index, &seconds); @@ -338,7 +338,7 @@ JSTaggedValue JSDate::UtcParseStringToMs(const CString &str) localHours = localTime / HUNDRED; localMinutes = localTime % HUNDRED; localMs = static_cast(MakeTime(localHours, localMinutes, 0, 0)); - if (indexPlus != CString::npos) { + if (indexPlus != PandaString::npos) { localMs = -localMs; } } @@ -356,7 +356,7 @@ JSTaggedValue JSDate::UtcParseStringToMs(const CString &str) return JSTaggedValue(timeValue); } // static -JSTaggedValue JSDate::IsoParseStringToMs(const CString &str) +JSTaggedValue JSDate::IsoParseStringToMs(const PandaString &str) { char flag = 0; int year; @@ -369,11 +369,11 @@ JSTaggedValue JSDate::IsoParseStringToMs(const CString &str) int index = 0; int len = str.length(); year = GetSignedNumFromString(str, len, &index); - CString::size_type indexT = str.find(FLAG_TIME, index); - CString::size_type indexZ = str.find(FLAG_UTC, index); - CString::size_type indexEndFlag = 0; + PandaString::size_type indexT = str.find(FLAG_TIME, index); + PandaString::size_type indexZ = str.find(FLAG_UTC, index); + PandaString::size_type indexEndFlag = 0; int64_t localMs = 0; - if (indexZ != CString::npos) { + if (indexZ != PandaString::npos) { indexEndFlag = indexZ; } else if (len >= MIN_LENGTH && str.at(len - INDEX_PLUS_NEG) == NEG) { indexEndFlag = len - INDEX_PLUS_NEG; @@ -382,7 +382,7 @@ JSTaggedValue JSDate::IsoParseStringToMs(const CString &str) indexEndFlag = len - INDEX_PLUS_NEG; flag = PLUS; } - if (indexT != CString::npos) { + if (indexT != PandaString::npos) { if ((indexT - index) == LENGTH_PER_TIME) { GetNumFromString(str, len, &index, &month); } else if ((indexT - index) == (LENGTH_PER_TIME + LENGTH_PER_TIME)) { @@ -413,7 +413,7 @@ JSTaggedValue JSDate::IsoParseStringToMs(const CString &str) if (indexEndFlag > 0) { int localHours = 0; int localMinutes = 0; - if (indexZ == CString::npos) { + if (indexZ == PandaString::npos) { GetNumFromString(str, len, &index, &localHours); GetNumFromString(str, len, &index, &localMinutes); if (flag == PLUS) { @@ -423,7 +423,7 @@ JSTaggedValue JSDate::IsoParseStringToMs(const CString &str) } } } - if (indexEndFlag == 0 && indexT != CString::npos) { + if (indexEndFlag == 0 && indexT != PandaString::npos) { localMs -= (GetLocalOffsetFromOS(localMs, true) * MS_PER_MINUTE); } @@ -446,27 +446,27 @@ JSTaggedValue JSDate::Parse(EcmaRuntimeCallInfo *argv) { ASSERT(argv); JSThread *thread = argv->GetThread(); - const CString isoPriStr = "(^|(\\+|-)(\\d{2}))"; - const CString isoDateStr = + const PandaString isoPriStr = "(^|(\\+|-)(\\d{2}))"; + const PandaString isoDateStr = "(((\\d{4})-(0?[1-9]|1[0-2])-(0?[1-9]|1[0-9]|2[0-9]|3[0-1]))" "|((\\d{4})-(0?[1-9]|1[0-2]))|(\\d{4}))"; - const CString isoTimeStr = + const PandaString isoTimeStr = "((T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])" "\\.(\\d{3}))|(T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]))|" "(T([01][0-9]|2[0-3]):([0-5][0-9]))|(T([01][0-9]|2[0-3])))" "($|Z|((\\+|-)(([01][0-9]|2[0-3]):([0-5][0-9]))))"; - const CString isoRegStr = isoPriStr + isoDateStr + "($|Z|(" + isoTimeStr + "))"; - const CString utcDateStr = + const PandaString isoRegStr = isoPriStr + isoDateStr + "($|Z|(" + isoTimeStr + "))"; + const PandaString utcDateStr = "^\\D*(0?[1-9]|1[0-9]|2[0-9]|3[0-1]) " "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\\d{4})"; - const CString timeStr = + const PandaString timeStr = "(( ([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]))|( ([01][0-9]|2[0-3]):([0-5][0-9])))" "($| *| GMT *| GMT((\\+|-)(\\d{4})) *)"; - const CString utcRegStr = utcDateStr + "($| *| GMT *| GMT((\\+|-)(\\d{4})) *|(" + timeStr + "))"; - const CString localDateStr = + const PandaString utcRegStr = utcDateStr + "($| *| GMT *| GMT((\\+|-)(\\d{4})) *|(" + timeStr + "))"; + const PandaString localDateStr = "^[a-zA-Z]* (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) " "(0?[1-9]|1[0-9]|2[0-9]|3[0-1]) (\\d{4})"; - const CString localRegStr = localDateStr + "($| *| GMT *| GMT((\\+|-)(\\d{4})) *|(" + timeStr + "))"; + const PandaString localRegStr = localDateStr + "($| *| GMT *| GMT((\\+|-)(\\d{4})) *|(" + timeStr + "))"; std::regex isoReg(isoRegStr); std::regex utcReg(utcRegStr); @@ -474,7 +474,7 @@ JSTaggedValue JSDate::Parse(EcmaRuntimeCallInfo *argv) JSHandle msg = base::BuiltinsBase::GetCallArg(argv, 0); JSHandle str = JSHandle::Cast(JSTaggedValue::ToString(thread, msg)); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); - CString date = ConvertToString(EcmaString::Cast(str->GetTaggedObject())); + PandaString date = ConvertToPandaString(EcmaString::Cast(str->GetTaggedObject())); if (std::regex_match(date, isoReg)) { return IsoParseStringToMs(date); } @@ -594,7 +594,7 @@ JSTaggedValue JSDate::GetTime() const } // static -CString JSDate::StrToTargetLength(const CString &str, int length) +PandaString JSDate::StrToTargetLength(const PandaString &str, int length) { int len; if (str[0] == NEG) { @@ -603,7 +603,7 @@ CString JSDate::StrToTargetLength(const CString &str, int length) len = static_cast(str.length()); } int dif = length - len; - CString sub; + PandaString sub; for (int i = 0; i < dif; i++) { sub += '0'; } @@ -628,32 +628,32 @@ bool JSDate::GetThisDateValues(std::array *date, bool isLo // 20.4.4.35 JSTaggedValue JSDate::ToDateString(JSThread *thread) const { - std::array monthName = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - std::array weekdayName = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + std::array monthName = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + std::array weekdayName = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; std::array fields = {0}; if (!GetThisDateValues(&fields, true)) { return JSTaggedValue(base::NAN_VALUE); } - CString year = StrToTargetLength(ToCString(fields[YEAR]), STR_LENGTH_YEAR); - CString day = StrToTargetLength(ToCString(fields[DAYS]), STR_LENGTH_OTHERS); - CString str = weekdayName[fields[WEEKDAY]] + SPACE + monthName[fields[MONTH]] + SPACE + day + SPACE + year; + PandaString year = StrToTargetLength(ToPandaString(fields[YEAR]), STR_LENGTH_YEAR); + PandaString day = StrToTargetLength(ToPandaString(fields[DAYS]), STR_LENGTH_OTHERS); + PandaString str = weekdayName[fields[WEEKDAY]] + SPACE + monthName[fields[MONTH]] + SPACE + day + SPACE + year; JSHandle result = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str); return result.GetTaggedValue(); } // static -CString JSDate::ToDateString(double timeMs) +PandaString JSDate::ToDateString(double timeMs) { if (std::isnan(timeMs)) { return "Invalid Date"; } - std::array monthName = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - std::array weekdayName = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + std::array monthName = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + std::array weekdayName = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; std::array fields = {0}; GetDateValues(timeMs, &fields, true); - CString localTime; + PandaString localTime; int localMin = 0; localMin = GetLocalOffsetFromOS(localMin, true); if (timeMs < CHINA_BEFORE_1900_MS && localMin == CHINA_AFTER_1901_MIN) { @@ -665,18 +665,18 @@ CString JSDate::ToDateString(double timeMs) localTime += NEG; localMin = -localMin; } - localTime = localTime + StrToTargetLength(ToCString(localMin / MINUTE_PER_HOUR), STR_LENGTH_OTHERS); - localTime = localTime + StrToTargetLength(ToCString(localMin % MINUTE_PER_HOUR), STR_LENGTH_OTHERS); - CString year = ToCString(fields[YEAR]); + localTime = localTime + StrToTargetLength(ToPandaString(localMin / MINUTE_PER_HOUR), STR_LENGTH_OTHERS); + localTime = localTime + StrToTargetLength(ToPandaString(localMin % MINUTE_PER_HOUR), STR_LENGTH_OTHERS); + PandaString year = ToPandaString(fields[YEAR]); year = StrToTargetLength(year, STR_LENGTH_YEAR); - CString weekday = weekdayName[fields[WEEKDAY]]; - CString month = monthName[fields[MONTH]]; - CString day = StrToTargetLength(ToCString(fields[DAYS]), STR_LENGTH_OTHERS); - CString hour = StrToTargetLength(ToCString(fields[HOUR]), STR_LENGTH_OTHERS); - CString minute = StrToTargetLength(ToCString(fields[MIN]), STR_LENGTH_OTHERS); - CString second = StrToTargetLength(ToCString(fields[SEC]), STR_LENGTH_OTHERS); - CString str = weekday + SPACE + month + SPACE + day + SPACE + year + SPACE + hour + COLON + minute + COLON + - second + SPACE + "GMT" + localTime; + PandaString weekday = weekdayName[fields[WEEKDAY]]; + PandaString month = monthName[fields[MONTH]]; + PandaString day = StrToTargetLength(ToPandaString(fields[DAYS]), STR_LENGTH_OTHERS); + PandaString hour = StrToTargetLength(ToPandaString(fields[HOUR]), STR_LENGTH_OTHERS); + PandaString minute = StrToTargetLength(ToPandaString(fields[MIN]), STR_LENGTH_OTHERS); + PandaString second = StrToTargetLength(ToPandaString(fields[SEC]), STR_LENGTH_OTHERS); + PandaString str = weekday + SPACE + month + SPACE + day + SPACE + year + SPACE + hour + COLON + minute + COLON + + second + SPACE + "GMT" + localTime; return str; } // 20.4.4.36 @@ -686,7 +686,7 @@ JSTaggedValue JSDate::ToISOString(JSThread *thread) const if (!GetThisDateValues(&fields, false)) { return JSTaggedValue(base::NAN_VALUE); } - CString year = ToCString(fields[YEAR]); + PandaString year = ToPandaString(fields[YEAR]); if (year[0] == NEG) { year = StrToTargetLength(year, STR_LENGTH_YEAR + STR_LENGTH_OTHERS); } else if (year.length() > STR_LENGTH_YEAR) { @@ -694,28 +694,28 @@ JSTaggedValue JSDate::ToISOString(JSThread *thread) const } else { year = StrToTargetLength(year, STR_LENGTH_YEAR); } - CString month = StrToTargetLength(ToCString(fields[MONTH] + 1), STR_LENGTH_OTHERS); - CString day = StrToTargetLength(ToCString(fields[DAYS]), STR_LENGTH_OTHERS); - CString hour = StrToTargetLength(ToCString(fields[HOUR]), STR_LENGTH_OTHERS); - CString minute = StrToTargetLength(ToCString(fields[MIN]), STR_LENGTH_OTHERS); - CString second = StrToTargetLength(ToCString(fields[SEC]), STR_LENGTH_OTHERS); - CString ms = StrToTargetLength(ToCString(fields[MS]), STR_LENGTH_OTHERS + 1); - CString str = + PandaString month = StrToTargetLength(ToPandaString(fields[MONTH] + 1), STR_LENGTH_OTHERS); + PandaString day = StrToTargetLength(ToPandaString(fields[DAYS]), STR_LENGTH_OTHERS); + PandaString hour = StrToTargetLength(ToPandaString(fields[HOUR]), STR_LENGTH_OTHERS); + PandaString minute = StrToTargetLength(ToPandaString(fields[MIN]), STR_LENGTH_OTHERS); + PandaString second = StrToTargetLength(ToPandaString(fields[SEC]), STR_LENGTH_OTHERS); + PandaString ms = StrToTargetLength(ToPandaString(fields[MS]), STR_LENGTH_OTHERS + 1); + PandaString str = year + NEG + month + NEG + day + FLAG_TIME + hour + COLON + minute + COLON + second + POINT + ms + FLAG_UTC; return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str).GetTaggedValue(); } -CString JSDate::GetLocaleTimeStr(const std::array &fields) const +PandaString JSDate::GetLocaleTimeStr(const std::array &fields) const { - CString hour; + PandaString hour; if (fields[HOUR] > MOUTH_PER_YEAR) { - hour = ToCString(fields[HOUR] - MOUTH_PER_YEAR); + hour = ToPandaString(fields[HOUR] - MOUTH_PER_YEAR); } else { - hour = ToCString(fields[HOUR]); + hour = ToPandaString(fields[HOUR]); } - CString minute = ToCString(fields[MIN]); - CString second = StrToTargetLength(ToCString(fields[SEC]), STR_LENGTH_OTHERS); - CString str = hour + COLON + minute + COLON + second; + PandaString minute = ToPandaString(fields[MIN]); + PandaString second = StrToTargetLength(ToPandaString(fields[SEC]), STR_LENGTH_OTHERS); + PandaString str = hour + COLON + minute + COLON + second; if (fields[HOUR] >= MOUTH_PER_YEAR) { str = "下午" + str; } else { @@ -724,17 +724,17 @@ CString JSDate::GetLocaleTimeStr(const std::array &fields) return str; } -CString JSDate::GetLocaleDateStr(const std::array &fields) const +PandaString JSDate::GetLocaleDateStr(const std::array &fields) const { - CString year; + PandaString year; if (fields[YEAR] < 0) { - year = ToCString(-fields[YEAR] + 1); + year = ToPandaString(-fields[YEAR] + 1); } else { - year = ToCString(fields[YEAR]); + year = ToPandaString(fields[YEAR]); } - CString month = ToCString(fields[MONTH] + 1); - CString day = ToCString(fields[DAYS]); - CString str = year + VIRGULE + month + VIRGULE + day; + PandaString month = ToPandaString(fields[MONTH] + 1); + PandaString day = ToPandaString(fields[DAYS]); + PandaString str = year + VIRGULE + month + VIRGULE + day; return str; } @@ -745,7 +745,7 @@ JSTaggedValue JSDate::ToLocaleDateString(JSThread *thread) const if (!GetThisDateValues(&fields, true)) { return JSTaggedValue(base::NAN_VALUE); } - CString str = GetLocaleDateStr(fields); + PandaString str = GetLocaleDateStr(fields); return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str).GetTaggedValue(); } @@ -756,8 +756,8 @@ JSTaggedValue JSDate::ToLocaleString(JSThread *thread) const if (!GetThisDateValues(&fields, true)) { return JSTaggedValue(base::NAN_VALUE); } - CString strDate = GetLocaleDateStr(fields); - CString strTime = GetLocaleTimeStr(fields); + PandaString strDate = GetLocaleDateStr(fields); + PandaString strTime = GetLocaleTimeStr(fields); return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(strDate + SPACE + strTime).GetTaggedValue(); } @@ -768,22 +768,22 @@ JSTaggedValue JSDate::ToLocaleTimeString(JSThread *thread) const if (!GetThisDateValues(&fields, true)) { return JSTaggedValue(base::NAN_VALUE); } - CString str = GetLocaleTimeStr(fields); + PandaString str = GetLocaleTimeStr(fields); return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str).GetTaggedValue(); } // 20.4.4.41 JSTaggedValue JSDate::ToString(JSThread *thread) const { - std::array weekdayName = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; - std::array monthName = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + std::array weekdayName = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + std::array monthName = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; int localMin = 0; std::array fields = {0}; if (!GetThisDateValues(&fields, true)) { return JSTaggedValue(base::NAN_VALUE); } - CString localTime; + PandaString localTime; localMin = GetLocalOffsetFromOS(localMin, true); if (static_cast(this->GetTimeValue().GetDouble()) < CHINA_BEFORE_1900_MS && localMin == CHINA_AFTER_1901_MIN) { @@ -795,18 +795,18 @@ JSTaggedValue JSDate::ToString(JSThread *thread) const localTime += NEG; localMin = -localMin; } - localTime = localTime + StrToTargetLength(ToCString(localMin / MINUTE_PER_HOUR), STR_LENGTH_OTHERS); - localTime = localTime + StrToTargetLength(ToCString(localMin % MINUTE_PER_HOUR), STR_LENGTH_OTHERS); - CString year = ToCString(fields[YEAR]); + localTime = localTime + StrToTargetLength(ToPandaString(localMin / MINUTE_PER_HOUR), STR_LENGTH_OTHERS); + localTime = localTime + StrToTargetLength(ToPandaString(localMin % MINUTE_PER_HOUR), STR_LENGTH_OTHERS); + PandaString year = ToPandaString(fields[YEAR]); year = StrToTargetLength(year, STR_LENGTH_YEAR); - CString weekday = weekdayName[fields[WEEKDAY]]; - CString month = monthName[fields[MONTH]]; - CString day = StrToTargetLength(ToCString(fields[DAYS]), STR_LENGTH_OTHERS); - CString hour = StrToTargetLength(ToCString(fields[HOUR]), STR_LENGTH_OTHERS); - CString minute = StrToTargetLength(ToCString(fields[MIN]), STR_LENGTH_OTHERS); - CString second = StrToTargetLength(ToCString(fields[SEC]), STR_LENGTH_OTHERS); - CString str = weekday + SPACE + month + SPACE + day + SPACE + year + SPACE + hour + COLON + minute + COLON + - second + SPACE + "GMT" + localTime; + PandaString weekday = weekdayName[fields[WEEKDAY]]; + PandaString month = monthName[fields[MONTH]]; + PandaString day = StrToTargetLength(ToPandaString(fields[DAYS]), STR_LENGTH_OTHERS); + PandaString hour = StrToTargetLength(ToPandaString(fields[HOUR]), STR_LENGTH_OTHERS); + PandaString minute = StrToTargetLength(ToPandaString(fields[MIN]), STR_LENGTH_OTHERS); + PandaString second = StrToTargetLength(ToPandaString(fields[SEC]), STR_LENGTH_OTHERS); + PandaString str = weekday + SPACE + month + SPACE + day + SPACE + year + SPACE + hour + COLON + minute + COLON + + second + SPACE + "GMT" + localTime; return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str).GetTaggedValue(); } @@ -818,7 +818,7 @@ JSTaggedValue JSDate::ToTimeString(JSThread *thread) const if (!GetThisDateValues(&fields, true)) { return JSTaggedValue(base::NAN_VALUE); } - CString localTime; + PandaString localTime; localMin = GetLocalOffsetFromOS(localMin, true); if (static_cast(this->GetTimeValue().GetDouble()) < CHINA_BEFORE_1900_MS && localMin == CHINA_AFTER_1901_MIN) { @@ -830,36 +830,36 @@ JSTaggedValue JSDate::ToTimeString(JSThread *thread) const localTime += NEG; localMin = -localMin; } - localTime = localTime + StrToTargetLength(ToCString(localMin / MINUTE_PER_HOUR), STR_LENGTH_OTHERS); - localTime = localTime + StrToTargetLength(ToCString(localMin % MINUTE_PER_HOUR), STR_LENGTH_OTHERS); - CString hour = StrToTargetLength(ToCString(fields[HOUR]), STR_LENGTH_OTHERS); - CString minute = StrToTargetLength(ToCString(fields[MIN]), STR_LENGTH_OTHERS); - CString second = StrToTargetLength(ToCString(fields[SEC]), STR_LENGTH_OTHERS); - CString str = hour + COLON + minute + COLON + second + SPACE + "GMT" + localTime; + localTime = localTime + StrToTargetLength(ToPandaString(localMin / MINUTE_PER_HOUR), STR_LENGTH_OTHERS); + localTime = localTime + StrToTargetLength(ToPandaString(localMin % MINUTE_PER_HOUR), STR_LENGTH_OTHERS); + PandaString hour = StrToTargetLength(ToPandaString(fields[HOUR]), STR_LENGTH_OTHERS); + PandaString minute = StrToTargetLength(ToPandaString(fields[MIN]), STR_LENGTH_OTHERS); + PandaString second = StrToTargetLength(ToPandaString(fields[SEC]), STR_LENGTH_OTHERS); + PandaString str = hour + COLON + minute + COLON + second + SPACE + "GMT" + localTime; return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str).GetTaggedValue(); } // 20.4.4.43 JSTaggedValue JSDate::ToUTCString(JSThread *thread) const { - std::array weekdayName = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; - std::array monthName = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + std::array weekdayName = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + std::array monthName = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; std::array fields = {0}; if (!GetThisDateValues(&fields, false)) { return JSTaggedValue(base::NAN_VALUE); } - CString year = ToCString(fields[YEAR]); + PandaString year = ToPandaString(fields[YEAR]); year = StrToTargetLength(year, STR_LENGTH_YEAR); - CString weekday = weekdayName[fields[WEEKDAY]]; - CString month = monthName[fields[MONTH]]; - CString day = StrToTargetLength(ToCString(fields[DAYS]), STR_LENGTH_OTHERS); - CString hour = StrToTargetLength(ToCString(fields[HOUR]), STR_LENGTH_OTHERS); - CString minute = StrToTargetLength(ToCString(fields[MIN]), STR_LENGTH_OTHERS); - CString second = StrToTargetLength(ToCString(fields[SEC]), STR_LENGTH_OTHERS); - CString ms = StrToTargetLength(ToCString(fields[MS]), STR_LENGTH_OTHERS); - CString str = weekday + COMMA + SPACE + day + SPACE + month + SPACE + year + SPACE + hour + COLON + minute + COLON + - second + SPACE + "GMT"; + PandaString weekday = weekdayName[fields[WEEKDAY]]; + PandaString month = monthName[fields[MONTH]]; + PandaString day = StrToTargetLength(ToPandaString(fields[DAYS]), STR_LENGTH_OTHERS); + PandaString hour = StrToTargetLength(ToPandaString(fields[HOUR]), STR_LENGTH_OTHERS); + PandaString minute = StrToTargetLength(ToPandaString(fields[MIN]), STR_LENGTH_OTHERS); + PandaString second = StrToTargetLength(ToPandaString(fields[SEC]), STR_LENGTH_OTHERS); + PandaString ms = StrToTargetLength(ToPandaString(fields[MS]), STR_LENGTH_OTHERS); + PandaString str = weekday + COMMA + SPACE + day + SPACE + month + SPACE + year + SPACE + hour + COLON + minute + + COLON + second + SPACE + "GMT"; return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str).GetTaggedValue(); } diff --git a/runtime/js_date.h b/runtime/js_date.h index 8f998e9c5a0d6995994bf83d3202adf20d40e850..ded1518dd48b8641ac8dbeed9e67355a5619c7e6 100644 --- a/runtime/js_date.h +++ b/runtime/js_date.h @@ -75,11 +75,11 @@ public: static double MakeTime(double hour, double min, double sec, double ms); static double MakeDate(double day, double time); static double TimeClip(double time); - static JSTaggedValue LocalParseStringToMs(const CString &str); - static JSTaggedValue UtcParseStringToMs(const CString &str); - static JSTaggedValue IsoParseStringToMs(const CString &str); - static int GetSignedNumFromString(const CString &str, int len, int *index); - static bool GetNumFromString(const CString &str, int len, int *index, int *num); + static JSTaggedValue LocalParseStringToMs(const PandaString &str); + static JSTaggedValue UtcParseStringToMs(const PandaString &str); + static JSTaggedValue IsoParseStringToMs(const PandaString &str); + static int GetSignedNumFromString(const PandaString &str, int len, int *index); + static bool GetNumFromString(const PandaString &str, int len, int *index, int *num); // 20.4.1.7 int64_t GetLocalOffsetInMin(const JSThread *thread, int64_t timeMs, bool isLocal); @@ -107,7 +107,7 @@ public: // 20.4.4.35 JSTaggedValue ToDateString(JSThread *thread) const; - static CString ToDateString(double timeMs); + static PandaString ToDateString(double timeMs); // 20.4.4.36 JSTaggedValue ToISOString(JSThread *thread) const; @@ -144,13 +144,13 @@ public: static double SetDateValues(const std::array *date, bool isLocal); static void GetDateValues(double timeMs, std::array *date, bool isLocal); static int64_t GetLocalOffsetFromOS(int64_t timeMs, bool isLocal); - static CString StrToTargetLength(const CString &str, int length); + static PandaString StrToTargetLength(const PandaString &str, int length); DECL_DUMP() private: bool GetThisDateValues(std::array *date, bool isLocal) const; - CString GetLocaleTimeStr(const std::array &fields) const; - CString GetLocaleDateStr(const std::array &fields) const; + PandaString GetLocaleTimeStr(const std::array &fields) const; + PandaString GetLocaleDateStr(const std::array &fields) const; static int64_t MathMod(int64_t a, int b); static constexpr int MINUTE_PER_HOUR = 60; diff --git a/runtime/js_date_time_format.cpp b/runtime/js_date_time_format.cpp index fcfd45912b40d5b1a2f66e75e3b18d9d9c29e566..7772150c9bce6a15d4f3be402b721f4a4d64604d 100644 --- a/runtime/js_date_time_format.cpp +++ b/runtime/js_date_time_format.cpp @@ -109,7 +109,7 @@ void JSDateTimeFormat::SetIcuLocale(JSThread *thread, JSHandle { EcmaVM *ecmaVm = thread->GetEcmaVM(); ObjectFactory *factory = ecmaVm->GetFactory(); - icu::Locale *icuPointer = ecmaVm->GetRegionFactory()->New(icuLocale); + icu::Locale *icuPointer = Runtime::GetCurrent()->GetInternalAllocator()->New(icuLocale); ASSERT(icuPointer != nullptr); JSTaggedValue data = obj->GetLocaleIcu(); if (data.IsHeapObject() && data.IsJSNativePointer()) { @@ -123,15 +123,14 @@ void JSDateTimeFormat::SetIcuLocale(JSThread *thread, JSHandle ecmaVm->PushToArrayDataList(*pointer); } -void JSDateTimeFormat::FreeIcuLocale(void *pointer, void *data) +void JSDateTimeFormat::FreeIcuLocale(void *pointer, [[maybe_unused]] void *data) { if (pointer == nullptr) { return; } auto icuLocale = reinterpret_cast(pointer); - icuLocale->~Locale(); if (data != nullptr) { - reinterpret_cast(data)->GetRegionFactory()->FreeBuffer(pointer); + Runtime::GetCurrent()->GetInternalAllocator()->Delete(icuLocale); } } @@ -149,7 +148,8 @@ void JSDateTimeFormat::SetIcuSimpleDateFormat(JSThread *thread, JSHandleGetEcmaVM(); ObjectFactory *factory = ecmaVm->GetFactory(); - icu::SimpleDateFormat *icuPointer = ecmaVm->GetRegionFactory()->New(icuSimpleDateTimeFormat); + auto allocator = Runtime::GetCurrent()->GetInternalAllocator(); + icu::SimpleDateFormat *icuPointer = allocator->New(icuSimpleDateTimeFormat); ASSERT(icuPointer != nullptr); JSTaggedValue data = obj->GetSimpleDateTimeFormatIcu(); if (data.IsHeapObject() && data.IsJSNativePointer()) { @@ -163,15 +163,14 @@ void JSDateTimeFormat::SetIcuSimpleDateFormat(JSThread *thread, JSHandlePushToArrayDataList(*pointer); } -void JSDateTimeFormat::FreeSimpleDateFormat(void *pointer, void *data) +void JSDateTimeFormat::FreeSimpleDateFormat(void *pointer, [[maybe_unused]] void *data) { if (pointer == nullptr) { return; } auto icuSimpleDateFormat = reinterpret_cast(pointer); - icuSimpleDateFormat->~SimpleDateFormat(); if (data != nullptr) { - reinterpret_cast(data)->GetRegionFactory()->FreeBuffer(pointer); + Runtime::GetCurrent()->GetInternalAllocator()->Delete(icuSimpleDateFormat); } } diff --git a/runtime/js_date_time_format.h b/runtime/js_date_time_format.h index 556ea859b17ff736bcf20c6becf3c6a24df3a102..2d2db9ec2785897a8b44b222568d01f6b97d84f7 100644 --- a/runtime/js_date_time_format.h +++ b/runtime/js_date_time_format.h @@ -19,7 +19,6 @@ #include "js_locale.h" namespace panda::ecmascript { -enum class CalendarOption : uint8_t { UNDEFINED = 0x01 }; enum class DateTimeStyleOption : uint8_t { FULL = 0x01, LONG, MEDIUM, SHORT, UNDEFINED, EXCEPTION }; enum class DefaultsOption : uint8_t { DATE = 0x01, TIME, ALL }; enum class HourCycleOption : uint8_t { H11 = 0x01, H12, H23, H24, UNDEFINED, EXCEPTION }; diff --git a/runtime/js_for_in_iterator.cpp b/runtime/js_for_in_iterator.cpp index 2715b7228fc5870af91e4fdbd92668872adb9cd0..5e51aaced230701c006cc08ab96bcc95a12bdeff 100644 --- a/runtime/js_for_in_iterator.cpp +++ b/runtime/js_for_in_iterator.cpp @@ -63,7 +63,7 @@ void JSForInIterator::FastGetAllEnumKeys(const JSThread *thread, const JSHandle< if (obj->IsJSPrimitiveRef() && JSPrimitiveRef::Cast(*obj)->IsString()) { elementIndex = JSPrimitiveRef::Cast(*obj)->GetStringLength(); for (uint32_t i = 0; i < elementIndex; i++) { - value.Update(factory->NewFromCanBeCompressString(ToCString(i)).GetTaggedValue()); + value.Update(factory->NewFromCanBeCompressString(ToPandaString(i)).GetTaggedValue()); TaggedQueue::PushFixedQueue(thread, remaining, value); } } else { @@ -72,14 +72,14 @@ void JSForInIterator::FastGetAllEnumKeys(const JSThread *thread, const JSHandle< uint32_t elementsLen = elements->GetLength(); for (uint32_t i = 0; i < elementsLen; ++i) { if (!elements->Get(i).IsHole()) { - value.Update(factory->NewFromCanBeCompressString(ToCString(i)).GetTaggedValue()); + value.Update(factory->NewFromCanBeCompressString(ToPandaString(i)).GetTaggedValue()); TaggedQueue::PushFixedQueue(thread, remaining, value); } } } else { JSHandle numberDic(elements); int size = numberDic->Size(); - CVector sortArr; + PandaVector sortArr; for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key = numberDic->GetKey(hashIndex); if (!key.IsUndefined() && !key.IsHole()) { @@ -91,7 +91,7 @@ void JSForInIterator::FastGetAllEnumKeys(const JSThread *thread, const JSHandle< } std::sort(sortArr.begin(), sortArr.end(), NumberDictionary::CompKey); for (const auto &entry : sortArr) { - value.Update(factory->NewFromCanBeCompressString(ToCString(entry.GetInt())).GetTaggedValue()); + value.Update(factory->NewFromCanBeCompressString(ToPandaString(entry.GetInt())).GetTaggedValue()); TaggedQueue::PushFixedQueue(thread, remaining, value); } } @@ -101,7 +101,7 @@ void JSForInIterator::FastGetAllEnumKeys(const JSThread *thread, const JSHandle< if (obj->IsJSGlobalObject()) { GlobalDictionary *dict = GlobalDictionary::Cast(obj->GetProperties().GetTaggedObject()); int size = dict->Size(); - CVector> sortArr; + PandaVector> sortArr; for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key = dict->GetKey(hashIndex); if (!key.IsUndefined() && !key.IsHole()) { @@ -163,7 +163,7 @@ void JSForInIterator::FastGetAllEnumKeys(const JSThread *thread, const JSHandle< } else { JSHandle nameDic(propertiesArr); int size = nameDic->Size(); - CVector> sortArr; + PandaVector> sortArr; for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key = nameDic->GetKey(hashIndex); if (key.IsString()) { diff --git a/runtime/js_function.cpp b/runtime/js_function.cpp index 5090fdb8d014297479077c1f790505930a9bae18..d3dd0733020b3ffcf16c5861033b7d09f8fca8ed 100644 --- a/runtime/js_function.cpp +++ b/runtime/js_function.cpp @@ -26,7 +26,6 @@ #include "plugins/ecmascript/runtime/js_promise.h" #include "plugins/ecmascript/runtime/js_proxy.h" #include "plugins/ecmascript/runtime/js_tagged_value-inl.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "plugins/ecmascript/runtime/object_factory.h" #include "plugins/ecmascript/runtime/tagged_array.h" @@ -152,7 +151,7 @@ JSTaggedValue JSFunction::NameGetter(JSThread *thread, const JSHandle if (target->GetPandaFile() == nullptr) { return JSTaggedValue::Undefined(); } - CString funcName = target->ParseFunctionName(); + PandaString funcName = target->ParseFunctionName(); if (funcName.empty()) { return thread->GlobalConstants()->GetEmptyString(); } @@ -327,7 +326,7 @@ JSTaggedValue JSFunction::CallInternal(JSThread *thread, const JSHandle values; + thread_local std::vector values; values.reserve(size); values.clear(); @@ -364,7 +363,7 @@ JSTaggedValue JSFunction::ConstructInternal(JSThread *thread, const JSHandle values; + thread_local std::vector values; values.reserve(size); values.clear(); diff --git a/runtime/js_hclass-inl.h b/runtime/js_hclass-inl.h index c962c1121e01ba27c8c50f2cbab451d021deaa85..c7b011b0dc0f6836e258af5450e696af304dde8b 100644 --- a/runtime/js_hclass-inl.h +++ b/runtime/js_hclass-inl.h @@ -20,7 +20,6 @@ #include "plugins/ecmascript/runtime/layout_info-inl.h" #include "plugins/ecmascript/runtime/transitions_dictionary.h" -#include "plugins/ecmascript/runtime/mem/assert_scope.h" namespace panda::ecmascript { inline JSHClass *JSHClass::Cast(const TaggedObject *object) @@ -92,7 +91,6 @@ void JSHClass::AddProtoTransitions(const JSThread *thread, const JSHandleGetLength() != 0); diff --git a/runtime/js_hclass.cpp b/runtime/js_hclass.cpp index 62d41219b84bd08a61d38c11c69e852c0c3501fa..72f610e981628e5af31c6a32d235300139b1fcd0 100644 --- a/runtime/js_hclass.cpp +++ b/runtime/js_hclass.cpp @@ -22,7 +22,6 @@ #include "plugins/ecmascript/runtime/ic/proto_change_details.h" #include "plugins/ecmascript/runtime/js_object-inl.h" #include "plugins/ecmascript/runtime/js_symbol.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "plugins/ecmascript/runtime/tagged_array-inl.h" #include "plugins/ecmascript/runtime/weak_vector-inl.h" @@ -90,7 +89,6 @@ JSHandle TransitionsDictionary::Remove(const JSThread *th void TransitionsDictionary::Rehash(const JSThread *thread, TransitionsDictionary *newTable) { - DISALLOW_GARBAGE_COLLECTION; if ((newTable == nullptr) || (newTable->Size() < EntriesCount())) { return; } @@ -118,8 +116,6 @@ void TransitionsDictionary::Rehash(const JSThread *thread, TransitionsDictionary // class JSHClass void JSHClass::Initialize(const JSThread *thread, uint32_t size, JSType type, uint32_t inlinedProps, uint32_t flags) { - DISALLOW_GARBAGE_COLLECTION; - new (&hclass_) HClass(flags, panda_file::SourceLang::ECMASCRIPT); hclass_.SetManagedObject(this); @@ -148,8 +144,6 @@ void JSHClass::Initialize(const JSThread *thread, uint32_t size, JSType type, ui void JSHClass::Copy(const JSThread *thread, const JSHClass *jshclass) { - DISALLOW_GARBAGE_COLLECTION; - // HClass fields SetBitField(jshclass->GetBitField()); SetBitField1(jshclass->GetBitField1()); @@ -320,7 +314,6 @@ void JSHClass::TransitionToDictionary(const JSThread *thread, const JSHandle newJshclass = CloneWithoutInlinedProperties(thread, jshclass); { - DISALLOW_GARBAGE_COLLECTION; // 2. Copy newJshclass->SetNumberOfProps(0); newJshclass->SetIsDictionaryMode(true); diff --git a/runtime/js_hclass.h b/runtime/js_hclass.h index 1fa45a580741f9812e8fffeab3b92a9102e137f3..7b28c15bc2c1a7644d14ce74ea8fd17b101487b7 100644 --- a/runtime/js_hclass.h +++ b/runtime/js_hclass.h @@ -1079,7 +1079,7 @@ public: return reinterpret_cast(reinterpret_cast(hclass) - MEMBER_OFFSET(JSHClass, hclass_)); } - static constexpr size_t BIT_FIELD_OFFSET = TaggedObjectSize() + HClass::GetDataOffset(); + static constexpr size_t BIT_FIELD_OFFSET = TaggedObjectSize() + ::panda::HClass::GetDataOffset(); SET_GET_PRIMITIVE_FIELD(BitField, uint32_t, BIT_FIELD_OFFSET, BIT_FIELD_OFFSET_END); static constexpr size_t BIT_FIELD1_OFFSET = BIT_FIELD_OFFSET + sizeof(uint32_t); SET_GET_PRIMITIVE_FIELD(BitField1, uint32_t, BIT_FIELD1_OFFSET, BIT_FIELD1_OFFSET_END); @@ -1102,7 +1102,7 @@ public: } DECL_DUMP() - static CString DumpJSType(JSType type); + static PandaString DumpJSType(JSType type); DECL_VISIT_OBJECT(PROTOTYPE_OFFSET, SIZE); diff --git a/runtime/js_invoker.cpp b/runtime/js_invoker.cpp index 66984f9b627f3a1a1527b27d7da5b3e4b2fd5010..c1dd4ad6c74ddd318210de6406049a1277e25164 100644 --- a/runtime/js_invoker.cpp +++ b/runtime/js_invoker.cpp @@ -20,7 +20,6 @@ #include "plugins/ecmascript/runtime/interpreter/interpreter-inl.h" #include "plugins/ecmascript/runtime/js_tagged_value.h" #include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "plugins/ecmascript/runtime/tagged_array-inl.h" #include "libpandabase/utils/span.h" @@ -63,7 +62,7 @@ JSTaggedValue InvokeJsFunction(JSThread *thread, const JSHandle &fun constexpr uint32_t extraSize = 3; // Include func newtarget and this auto length = arguments->GetLength(); - CVector argArray; + PandaVector argArray; argArray.reserve(length + extraSize); argArray.emplace_back(func.GetTaggedType()); diff --git a/runtime/js_invoker.h b/runtime/js_invoker.h index 15239798608e0f0feb42a5a80501a6813d7261c7..a852121e95f6dd20ac2e16a63020fe9a331815f8 100644 --- a/runtime/js_invoker.h +++ b/runtime/js_invoker.h @@ -20,7 +20,6 @@ #include "plugins/ecmascript/runtime/js_handle.h" #include "plugins/ecmascript/runtime/js_object.h" #include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" namespace panda::ecmascript { class JsInvoker { @@ -56,7 +55,7 @@ public: JSTaggedValue Invoke(JSThread *thread); private: - CVector> args_ {}; + PandaVector> args_ {}; }; JSTaggedValue InvokeJsFunction(JSThread *thread, const JSHandle &func, const JSHandle &obj, diff --git a/runtime/js_locale.cpp b/runtime/js_locale.cpp index 6f985b0fce91ad982c830fc4ec89c7f711ec197f..d5c2d30b4b32b594e4da0f1bb3767eea47c38b1e 100644 --- a/runtime/js_locale.cpp +++ b/runtime/js_locale.cpp @@ -55,7 +55,7 @@ bool JSLocale::IsStructurallyValidLanguageTag(const JSHandle &tag) std::string JSLocale::ConvertToStdString(const JSHandle &ecmaStr) { - return std::string(ConvertToString(*ecmaStr, StringConvertedUsage::LOGICOPERATION)); + return std::string(ConvertToPandaString(*ecmaStr, StringConvertedUsage::LOGICOPERATION)); } // 6.2.3 CanonicalizeUnicodeLocaleId( locale ) diff --git a/runtime/js_locale.h b/runtime/js_locale.h index 33d4a5a9cf1136a712801dfa9f9a9811bd48471b..d3eba38bd2617c723eeebe091869933e23605db3 100644 --- a/runtime/js_locale.h +++ b/runtime/js_locale.h @@ -19,7 +19,6 @@ #include "plugins/ecmascript/runtime/ecma_macros.h" #include "plugins/ecmascript/runtime/js_array.h" #include "plugins/ecmascript/runtime/js_object.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "ohos/init_data.h" #include "unicode/basictz.h" #include "unicode/brkiter.h" @@ -50,18 +49,6 @@ namespace panda::ecmascript { enum class OptionType : uint8_t { STRING = 0x01, BOOLEAN }; enum class LocaleMatcherOption : uint8_t { LOOKUP = 0x01, BEST_FIT, EXCEPTION }; enum class FormatMatcherOption : uint8_t { BASIC = 0x01, BEST_FIT, EXCEPTION }; -enum class LocaleType : uint8_t { - LITERAL = 0x01, - NUMBER, - PLUS_SIGN, - MINUS_SIGN, - PERCENT_SIGN, - UNIT_PREFIX, - UNIT_SUFFIX, - CURRENCY_CODE, - CURRENCY_PREFIX, - CURRENCY_SUFFIX, -}; enum class RoundingType : uint8_t { FRACTIONDIGITS = 0x01, SIGNIFICANTDIGITS, COMPACTROUNDING, EXCEPTION }; enum class NotationOption : uint8_t { STANDARD = 0x01, SCIENTIFIC, ENGINEERING, COMPACT, EXCEPTION }; @@ -168,15 +155,14 @@ public: return reinterpret_cast(result); } - static void FreeIcuLocale(void *pointer, void *data) + static void FreeIcuLocale(void *pointer, [[maybe_unused]] void *data) { if (pointer == nullptr) { return; } auto icuLocale = reinterpret_cast(pointer); - icuLocale->~Locale(); if (data != nullptr) { - reinterpret_cast(data)->GetRegionFactory()->FreeBuffer(pointer); + Runtime::GetCurrent()->GetInternalAllocator()->Delete(icuLocale); } } diff --git a/runtime/js_map_iterator.cpp b/runtime/js_map_iterator.cpp index 1781885f18b360cbb615f5df0e44660efba0a322..b3f273b8f788fe6b58375d026b88a1bc1f90fddb 100644 --- a/runtime/js_map_iterator.cpp +++ b/runtime/js_map_iterator.cpp @@ -83,7 +83,6 @@ JSTaggedValue JSMapIterator::Next(EcmaRuntimeCallInfo *argv) void JSMapIterator::Update(const JSThread *thread) { - [[maybe_unused]] DisallowGarbageCollection noGc; JSTaggedValue iteratedMap = GetIteratedMap(); if (iteratedMap.IsUndefined()) { return; diff --git a/runtime/js_method.cpp b/runtime/js_method.cpp index c180ec2242ec5ac23817f27e70484938d9a22d1a..d96e59bd6a683c82ee99ec4fb214c3d295444fdf 100644 --- a/runtime/js_method.cpp +++ b/runtime/js_method.cpp @@ -24,7 +24,7 @@ JSMethod::~JSMethod() } // It's not allowed '#' token appear in ECMA function(method) name, which discriminates same names in panda methods. -CString JSMethod::ParseFunctionName() const +PandaString JSMethod::ParseFunctionName() const { auto *name = GetStringDataAnnotation(Method::AnnotationField::FUNCTION_NAME).data; if (name == nullptr) { diff --git a/runtime/js_method.h b/runtime/js_method.h index 85471ddee79d33917c6fe31b013756872af27540..35dd00177afff6875f5b17a647dfddb41ab20178 100644 --- a/runtime/js_method.h +++ b/runtime/js_method.h @@ -16,7 +16,8 @@ #ifndef ECMASCRIPT_JS_METHOD_H #define ECMASCRIPT_JS_METHOD_H -#include "plugins/ecmascript/runtime/mem/c_string.h" +#include "plugins/ecmascript/runtime/js_tagged_value.h" +#include "plugins/ecmascript/runtime/mem/ecma_string.h" #include "include/method.h" #include "libpandafile/file.h" @@ -116,7 +117,7 @@ public: return callType_; } - CString ParseFunctionName() const; + PandaString ParseFunctionName() const; std::string GetFullName(); void SetCallTypeFromAnnotation(); diff --git a/runtime/js_number_format.h b/runtime/js_number_format.h index ae58956b3e580f294bffca5d27896857e79f489e..ddc5ce2317b8280e77abf92d22d3f34aaf53d2ae 100644 --- a/runtime/js_number_format.h +++ b/runtime/js_number_format.h @@ -97,15 +97,14 @@ public: return reinterpret_cast(result); } - static void FreeIcuNumberformat(void *pointer, void *data) + static void FreeIcuNumberformat(void *pointer, [[maybe_unused]] void *data) { if (pointer == nullptr) { return; } auto icuNumberformat = reinterpret_cast(pointer); - icuNumberformat->~LocalizedNumberFormatter(); if (data != nullptr) { - reinterpret_cast(data)->GetRegionFactory()->FreeBuffer(pointer); + Runtime::GetCurrent()->GetInternalAllocator()->Delete(icuNumberformat); } } diff --git a/runtime/js_object.cpp b/runtime/js_object.cpp index 3e749b2b3c7a58d1407678fceee347be6286027e..2cbb9f167bf7a943c5cfa5acb2f65b5718ce8795 100644 --- a/runtime/js_object.cpp +++ b/runtime/js_object.cpp @@ -34,7 +34,6 @@ namespace panda::ecmascript { PropertyAttributes::PropertyAttributes(const PropertyDescriptor &desc) { - DISALLOW_GARBAGE_COLLECTION; if (desc.HasWritable()) { SetWritable(desc.IsWritable()); } @@ -185,7 +184,6 @@ bool JSObject::AddElementInternal(JSThread *thread, const JSHandle &re { bool isDictionary = receiver->GetJSHClass()->IsDictionaryElement(); if (receiver->IsJSArray()) { - DISALLOW_GARBAGE_COLLECTION; JSHandle arr(receiver); uint32_t oldLength = arr->GetArrayLength(); if (index >= oldLength) { @@ -276,7 +274,6 @@ void JSObject::GetAllKeys(const JSThread *thread, const JSHandle &obj, // For Serialization use. Does not support JSGlobalObject void JSObject::GetAllKeys(const JSThread *thread, const JSHandle &obj, std::vector &keyVector) { - DISALLOW_GARBAGE_COLLECTION; ASSERT_PRINT(!obj->IsJSGlobalObject(), "Do not support get key of JSGlobal Object"); TaggedArray *array = TaggedArray::Cast(obj->GetProperties().GetTaggedObject()); if (!array->IsDictionaryMode()) { @@ -410,7 +407,6 @@ JSHandle JSObject::GetEnumElementKeys(JSThread *thread, const JSHan uint32_t JSObject::GetNumberOfKeys() { - DISALLOW_GARBAGE_COLLECTION; TaggedArray *array = TaggedArray::Cast(GetProperties().GetTaggedObject()); if (!array->IsDictionaryMode()) { @@ -435,7 +431,6 @@ bool JSObject::GlobalSetProperty(JSThread *thread, const JSHandle uint32_t JSObject::GetNumberOfElements() { - DISALLOW_GARBAGE_COLLECTION; uint32_t numOfElements = 0; if (IsJSPrimitiveRef() && JSPrimitiveRef::Cast(this)->IsString()) { numOfElements = JSPrimitiveRef::Cast(this)->GetStringLength(); @@ -1871,7 +1866,6 @@ void JSObject::AddAccessor(JSThread *thread, const JSHandle &obj, bool JSObject::UpdatePropertyInDictionary(const JSThread *thread, JSTaggedValue key, JSTaggedValue value) { - [[maybe_unused]] DisallowGarbageCollection noGc; NameDictionary *dict = NameDictionary::Cast(GetProperties().GetTaggedObject()); int entry = dict->FindEntry(key); if (entry == -1) { diff --git a/runtime/js_object.h b/runtime/js_object.h index d23dd1722ab6a853d3da6dd4369f1db81a626890..9759e775c3de33605a77ad633eb2ad25749b6149 100644 --- a/runtime/js_object.h +++ b/runtime/js_object.h @@ -27,7 +27,6 @@ #include "plugins/ecmascript/runtime/js_native_pointer.h" #include "plugins/ecmascript/runtime/js_tagged_value.h" #include "plugins/ecmascript/runtime/mem/object_xray.h" -#include "plugins/ecmascript/runtime/mem/slots.h" #include "plugins/ecmascript/runtime/object_operator.h" #include "plugins/ecmascript/runtime/property_attributes.h" #include "plugins/ecmascript/runtime/tagged_array.h" diff --git a/runtime/js_plural_rules.cpp b/runtime/js_plural_rules.cpp index a31b17cf0917ab3cd51b5752ba1b2fb0cd06e9d8..3009dc7fd7f98c3095d7a2f79cc180dc514d3f86 100644 --- a/runtime/js_plural_rules.cpp +++ b/runtime/js_plural_rules.cpp @@ -49,7 +49,7 @@ void JSPluralRules::SetIcuNumberFormatter(JSThread *thread, const JSHandleGetFactory(); icu::number::LocalizedNumberFormatter *icuPointer = - ecmaVm->GetRegionFactory()->New(icuNF); + Runtime::GetCurrent()->GetInternalAllocator()->New(icuNF); ASSERT(icuPointer != nullptr); JSTaggedValue data = pluralRules->GetIcuNF(); if (data.IsHeapObject() && data.IsJSNativePointer()) { @@ -86,7 +86,7 @@ void JSPluralRules::SetIcuPluralRules(JSThread *thread, const JSHandleGetEcmaVM(); ObjectFactory *factory = ecmaVm->GetFactory(); - icu::PluralRules *icuPointer = ecmaVm->GetRegionFactory()->New(icuPR); + icu::PluralRules *icuPointer = Runtime::GetCurrent()->GetInternalAllocator()->New(icuPR); ASSERT(icuPointer != nullptr); JSTaggedValue data = pluralRules->GetIcuPR(); if (data.IsHeapObject() && data.IsJSNativePointer()) { diff --git a/runtime/js_primitive_ref.cpp b/runtime/js_primitive_ref.cpp index 2e1566a5b1a09988dbdc7ddfef7ad344d58f8183..8bff5a8d955a7e37d40daf47afd2821aa168ed20 100644 --- a/runtime/js_primitive_ref.cpp +++ b/runtime/js_primitive_ref.cpp @@ -17,7 +17,6 @@ #include "plugins/ecmascript/runtime/ecma_string-inl.h" #include "plugins/ecmascript/runtime/ecma_vm.h" #include "plugins/ecmascript/runtime/global_env.h" -#include "plugins/ecmascript/runtime/mem/assert_scope-inl.h" #include "plugins/ecmascript/runtime/object_factory.h" namespace panda::ecmascript { @@ -50,7 +49,6 @@ bool JSPrimitiveRef::StringGetIndexProperty(const JSThread *thread, const JSHand { uint16_t tmpChar; { - DISALLOW_GARBAGE_COLLECTION; EcmaString *str = EcmaString::Cast(JSPrimitiveRef::Cast(*obj)->GetValue().GetTaggedObject()); if (str->GetLength() <= index) { return false; diff --git a/runtime/js_promise.h b/runtime/js_promise.h index 3a9cb10326dd24d448eeecb4e097e733ed0ba730..2e2e3202bf459d7687010870c410676285fc0721 100644 --- a/runtime/js_promise.h +++ b/runtime/js_promise.h @@ -26,7 +26,6 @@ namespace panda::ecmascript { enum class PromiseStatus : uint32_t { PENDING = 0, FULFILLED, REJECTED }; -enum class PromiseType : uint32_t { RESOLVE = 0, REJECT }; enum class PromiseRejectionEvent : uint32_t { REJECT = 0, HANDLE }; class PromiseReaction final : public Record { diff --git a/runtime/js_relative_time_format.h b/runtime/js_relative_time_format.h index ba92496c7a6851fdee2409262d26ff9659248703..529d8ea9678756d280cf004097a043f81d872b59 100644 --- a/runtime/js_relative_time_format.h +++ b/runtime/js_relative_time_format.h @@ -69,15 +69,14 @@ public: return reinterpret_cast(result); } - static void FreeIcuRTFFormatter(void *pointer, void *data) + static void FreeIcuRTFFormatter(void *pointer, [[maybe_unused]] void *data) { if (pointer == nullptr) { return; } auto icuFormatter = reinterpret_cast(pointer); - icuFormatter->~RelativeDateTimeFormatter(); if (data != nullptr) { - reinterpret_cast(data)->GetRegionFactory()->FreeBuffer(pointer); + Runtime::GetCurrent()->GetInternalAllocator()->Delete(icuFormatter); } } diff --git a/runtime/js_serializer.h b/runtime/js_serializer.h index 99a12bf186a4ef037a76cfaf753e6e9800e665c2..484664557a9b81204f09414e4094dc47e5cd45bb 100644 --- a/runtime/js_serializer.h +++ b/runtime/js_serializer.h @@ -230,7 +230,7 @@ private: ecmascript::JSSerializer valueSerializer_; std::unique_ptr data_; - CVector arrayBufferIdxs_; + PandaVector arrayBufferIdxs_; }; class Deserializer { diff --git a/runtime/js_set_iterator.cpp b/runtime/js_set_iterator.cpp index 9cb6d1a97e7922f82de5669e91ae49910a3e4ef7..1128eb557be35e551c295e61ae9d485a2e2c9048 100644 --- a/runtime/js_set_iterator.cpp +++ b/runtime/js_set_iterator.cpp @@ -77,7 +77,6 @@ JSTaggedValue JSSetIterator::Next(EcmaRuntimeCallInfo *argv) void JSSetIterator::Update(const JSThread *thread) { - [[maybe_unused]] DisallowGarbageCollection noGc; JSTaggedValue iteratedSet = GetIteratedSet(); if (iteratedSet.IsUndefined()) { return; diff --git a/runtime/js_stable_array.cpp b/runtime/js_stable_array.cpp index 9da15c51b2b257bc4fba5fd8bd2eb4c31cd91d2a..88aae1333e51b52fa05b568bbb4799edb3809b47 100644 --- a/runtime/js_stable_array.cpp +++ b/runtime/js_stable_array.cpp @@ -48,7 +48,6 @@ JSTaggedValue JSStableArray::Push(JSHandle receiver, EcmaRuntimeCallInf JSTaggedValue JSStableArray::Pop(JSHandle receiver, EcmaRuntimeCallInfo *argv) { - DISALLOW_GARBAGE_COLLECTION; JSThread *thread = argv->GetThread(); uint32_t length = receiver->GetArrayLength(); if (length == 0) { @@ -160,7 +159,6 @@ JSTaggedValue JSStableArray::Splice(JSHandle receiver, EcmaRuntimeCallI JSTaggedValue JSStableArray::Shift(JSHandle receiver, EcmaRuntimeCallInfo *argv) { - DISALLOW_GARBAGE_COLLECTION; JSThread *thread = argv->GetThread(); uint32_t length = receiver->GetArrayLength(); if (length == 0) { @@ -221,7 +219,7 @@ JSTaggedValue JSStableArray::Join(JSHandle receiver, EcmaRuntimeCallInf TaggedArray *elements = TaggedArray::Cast(receiver->GetElements().GetTaggedObject()); size_t allocateLength = 0; bool isOneByte = (sep != JSStableArray::SeparatorFlag::MINUS_ONE) || sepStringHandle->IsUtf8(); - CVector> vec; + PandaVector> vec; JSMutableHandle elementHandle(thread, JSTaggedValue::Undefined()); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); for (uint32_t k = 0; k < length; k++) { @@ -246,7 +244,6 @@ JSTaggedValue JSStableArray::Join(JSHandle receiver, EcmaRuntimeCallInf allocateLength += sepLength * (length - 1); auto newString = EcmaString::AllocStringObject(allocateLength, isOneByte, thread->GetEcmaVM()); int current = 0; - DISALLOW_GARBAGE_COLLECTION; for (uint32_t k = 0; k < length; k++) { if (k > 0) { if (sep >= 0) { diff --git a/runtime/js_tagged_value-inl.h b/runtime/js_tagged_value-inl.h index fb5ef74df3d62a7533261f2357c51fd910392212..e84459350ef49e0f392fcd31e5cc709981c5777b 100644 --- a/runtime/js_tagged_value-inl.h +++ b/runtime/js_tagged_value-inl.h @@ -31,7 +31,6 @@ #include "plugins/ecmascript/runtime/js_symbol.h" #include "plugins/ecmascript/runtime/js_tagged_number.h" #include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "plugins/ecmascript/runtime/mem/tagged_object-inl.h" #include "plugins/ecmascript/runtime/object_factory.h" @@ -111,7 +110,7 @@ inline JSTaggedNumber JSTaggedValue::ToNumber(JSThread *thread, const JSHandle buf; // Span will use buf.data(), shouldn't define inside 'if' + [[maybe_unused]] PandaVector buf; // Span will use buf.data(), shouldn't define inside 'if' if (UNLIKELY(strObj->IsUtf16())) { size_t len = base::utf_helper::Utf16ToUtf8Size(strObj->GetDataUtf16(), strLen) - 1; buf.reserve(len); diff --git a/runtime/js_tagged_value.h b/runtime/js_tagged_value.h index 337fb1f9e91406f0c967e52930357e4d78577ddc..ebf9662c0d83fd415f9d8f2db161d46d521f3b63 100644 --- a/runtime/js_tagged_value.h +++ b/runtime/js_tagged_value.h @@ -16,7 +16,8 @@ #ifndef ECMASCRIPT_JS_TAGGED_VALUE_H #define ECMASCRIPT_JS_TAGGED_VALUE_H -#include "plugins/ecmascript/runtime/mem/c_string.h" +#include "plugins/ecmascript/runtime/mem/ecma_string.h" +#include "plugins/ecmascript/runtime/mem/tagged_object.h" #include "include/coretypes/tagged_value.h" namespace panda::ecmascript { @@ -337,7 +338,7 @@ public: void DumpTaggedValue(JSThread *thread, std::ostream &os) const DUMP_API_ATTR; void Dump(JSThread *thread, std::ostream &os) const DUMP_API_ATTR; void D() const DUMP_API_ATTR; - void DumpForSnapshot(JSThread *thread, std::vector> &vec, + void DumpForSnapshot(JSThread *thread, std::vector> &vec, bool isVmMode = true) const; static void DV(JSTaggedType val) DUMP_API_ATTR; diff --git a/runtime/js_thread.cpp b/runtime/js_thread.cpp index e7c5e6abeda0df2c006f602ae1fb9cc603303fb1..227ecc6197bfe420d64faca367961e399ecd2cc9 100644 --- a/runtime/js_thread.cpp +++ b/runtime/js_thread.cpp @@ -28,7 +28,6 @@ namespace panda::ecmascript { JSThread *JSThread::Create(Runtime *runtime, PandaVM *vm) { auto jsThread = new JSThread(runtime, vm); - jsThread->regionFactory_ = EcmaVM::Cast(vm)->GetRegionFactory(); jsThread->InitBuffers(); JSThread::SetCurrent(jsThread); jsThread->NativeCodeBegin(); @@ -40,8 +39,7 @@ JSThread::JSThread(Runtime *runtime, PandaVM *vm) panda_file::SourceLang::ECMASCRIPT) { SetLanguageContext(runtime->GetLanguageContext(panda_file::SourceLang::ECMASCRIPT)); - auto chunk = EcmaVM::Cast(vm)->GetChunk(); - globalStorage_ = chunk->New(chunk); + globalStorage_ = runtime->GetInternalAllocator()->New(); internalCallParams_ = new InternalCallParams(); propertiesCache_ = new PropertiesCache(); } @@ -55,9 +53,8 @@ JSThread::~JSThread() currentHandleStorageIndex_ = -1; handleScopeCount_ = 0; handleScopeStorageNext_ = handleScopeStorageEnd_ = nullptr; - EcmaVM::Cast(GetVM())->GetChunk()->Delete(globalStorage_); + Runtime::GetCurrent()->GetInternalAllocator()->Delete(globalStorage_); - regionFactory_ = nullptr; if (internalCallParams_ != nullptr) { delete internalCallParams_; internalCallParams_ = nullptr; diff --git a/runtime/js_thread.h b/runtime/js_thread.h index a42557415e0d1fe0705c70404f70c93b27af1304..0dc3acc6fc154c9a5d899a1e582015e63ac934c5 100644 --- a/runtime/js_thread.h +++ b/runtime/js_thread.h @@ -16,7 +16,7 @@ #ifndef ECMASCRIPT_JS_THREAD_H #define ECMASCRIPT_JS_THREAD_H -#include "mem/c_string.h" +#include "mem/ecma_string.h" #include "runtime/include/thread.h" #include "include/managed_thread.h" @@ -27,17 +27,13 @@ namespace panda::ecmascript { class EcmaVM; -class RegionFactory; class EcmascriptEnvironment; class InternalCallParams; class PropertiesCache; -enum class MarkStatus : uint8_t { READY_TO_MARK, MARKING, MARK_FINISHED }; - class JSThread : public ManagedThread { public: static constexpr int CONCURRENT_MARKING_BITFIELD_NUM = 2; - using MarkStatusBits = BitField; using Address = uintptr_t; static JSThread *Cast(ManagedThread *thread) { @@ -102,11 +98,6 @@ public: bool DoStackOverflowCheck(const JSTaggedType *sp); - RegionFactory *GetRegionFactory() const - { - return regionFactory_; - } - void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1); uintptr_t *ExpandHandleStorage(); @@ -263,30 +254,6 @@ public: return MEMBER_OFFSET(JSThread, currentFrame_); } - void SetMarkStatus(MarkStatus status) - { - uint64_t newVal = MarkStatusBits::Update(threadStateBitField_, status); - threadStateBitField_ = newVal; - } - - bool IsReadyToMark() const - { - auto status = MarkStatusBits::Decode(threadStateBitField_); - return status == MarkStatus::READY_TO_MARK; - } - - bool IsMarking() const - { - auto status = MarkStatusBits::Decode(threadStateBitField_); - return status == MarkStatus::MARKING; - } - - bool IsMarkFinished() const - { - auto status = MarkStatusBits::Decode(threadStateBitField_); - return status == MarkStatus::MARK_FINISHED; - } - bool CheckSafepoint() const; void SetGetStackSignal(bool isParseStack) @@ -354,7 +321,6 @@ private: // MM: handles, global-handles, and aot-stubs. int nestedLevel_ = 0; - RegionFactory *regionFactory_ {nullptr}; JSTaggedType *handleScopeStorageNext_ {nullptr}; JSTaggedType *handleScopeStorageEnd_ {nullptr}; std::vector *> handleStorageNodes_ {}; diff --git a/runtime/layout_info.cpp b/runtime/layout_info.cpp index 1211b9e8f7b573b9ee6bf1f93de2b03babcb1000..5271d7a2f8e3a00ef18ab2e5e2d4655327e75d2e 100644 --- a/runtime/layout_info.cpp +++ b/runtime/layout_info.cpp @@ -16,13 +16,11 @@ #include "plugins/ecmascript/runtime/layout_info-inl.h" #include "plugins/ecmascript/runtime/ecma_string.h" #include "plugins/ecmascript/runtime/js_symbol.h" -#include "plugins/ecmascript/runtime/mem/assert_scope-inl.h" namespace panda::ecmascript { void LayoutInfo::AddKey(const JSThread *thread, [[maybe_unused]] int index, const JSTaggedValue &key, const PropertyAttributes &attr) { - DISALLOW_GARBAGE_COLLECTION; int number = NumberOfElements(); ASSERT(attr.GetOffset() == static_cast(number)); ASSERT(number + 1 <= GetPropertiesCapacity()); @@ -48,7 +46,6 @@ void LayoutInfo::GetAllKeys(const JSThread *thread, int end, int offset, TaggedA ASSERT_PRINT(offset + end <= static_cast(keyArray->GetLength()), "keyArray capacity is not enough for dictionary"); - DISALLOW_GARBAGE_COLLECTION; int enumKeys = 0; for (int i = 0; i < end; i++) { JSTaggedValue key = GetKey(i); @@ -88,7 +85,6 @@ void LayoutInfo::GetAllEnumKeys(const JSThread *thread, int end, int offset, Tag ASSERT_PRINT(offset + end <= static_cast(keyArray->GetLength()), "keyArray capacity is not enough for dictionary"); - DISALLOW_GARBAGE_COLLECTION; int enumKeys = 0; for (int i = 0; i < end; i++) { JSTaggedValue key = GetKey(i); @@ -102,7 +98,6 @@ void LayoutInfo::GetAllEnumKeys(const JSThread *thread, int end, int offset, Tag void LayoutInfo::GetAllNames(const JSThread *thread, int end, const JSHandle &keyArray, uint32_t *length) { - DISALLOW_GARBAGE_COLLECTION; int arrayIndex = 0; for (int i = 0; i < end; i++) { JSTaggedValue key = GetKey(i); diff --git a/runtime/literal_data_extractor.h b/runtime/literal_data_extractor.h index 2c467e8f73fbf1c6605c34d0fe2aaddf832cdb50..5ef5938a6abca266e9665aefba35faa98dbb7de6 100644 --- a/runtime/literal_data_extractor.h +++ b/runtime/literal_data_extractor.h @@ -22,8 +22,6 @@ namespace panda::ecmascript { using EntityId = panda_file::File::EntityId; -enum class FieldTag : uint8_t { OBJECTLITERAL = 0, ARRAYLITERAL }; - class LiteralDataExtractor { public: explicit LiteralDataExtractor() = default; diff --git a/runtime/mem/allocator-inl.h b/runtime/mem/allocator-inl.h deleted file mode 100644 index 413cb1be32f177fcd89a249e60c5c24ac9489474..0000000000000000000000000000000000000000 --- a/runtime/mem/allocator-inl.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_ALLOCATOR_INL_H -#define ECMASCRIPT_MEM_ALLOCATOR_INL_H - -#include - -#include "plugins/ecmascript/runtime/mem/allocator.h" -#include "plugins/ecmascript/runtime/mem/concurrent_sweeper.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/space.h" -#include "plugins/ecmascript/runtime/free_object.h" - -namespace panda::ecmascript { -BumpPointerAllocator::BumpPointerAllocator(const Space *space) - : BumpPointerAllocator(space->GetAllocateAreaBegin(), space->GetAllocateAreaEnd()) -{ -} - -BumpPointerAllocator::BumpPointerAllocator(uintptr_t begin, uintptr_t end) : begin_(begin), top_(begin), end_(end) {} - -void BumpPointerAllocator::Reset() -{ - begin_ = 0; - top_ = 0; - end_ = 0; -} - -void BumpPointerAllocator::Reset(uintptr_t begin, uintptr_t end) -{ - begin_ = begin; - top_ = begin; - end_ = end; -} - -void BumpPointerAllocator::Reset(const Space *space) -{ - Reset(space->GetAllocateAreaBegin(), space->GetAllocateAreaEnd()); -} - -uintptr_t BumpPointerAllocator::Allocate(size_t size) -{ - if (UNLIKELY(size == 0)) { - LOG_ECMA_MEM(FATAL) << "size must have a size bigger than 0"; - UNREACHABLE(); - } - size = AlignUp(size, static_cast(MemAlignment::MEM_ALIGN_OBJECT)); - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - if (UNLIKELY(top_ + size > end_)) { - return 0; - } - uintptr_t result = top_; - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - top_ += size; - return result; -} - -FreeListAllocator::FreeListAllocator(const Space *space) : heap_(space->GetHeap()), type_(space->GetSpaceType()) -{ - freeList_ = std::make_unique(); - bpAllocator_.Reset(space); - FreeObject::Cast(bpAllocator_.GetTop())->SetAvailable(bpAllocator_.Available()); - FreeObject::Cast(bpAllocator_.GetTop())->SetNext(nullptr); -} - -void FreeListAllocator::Reset(const Space *space) -{ - heap_ = space->GetHeap(); - type_ = space->GetSpaceType(); - sweeping_ = false; - freeList_ = std::make_unique(); - bpAllocator_.Reset(space); - FreeObject::FillFreeObject(heap_->GetEcmaVM(), bpAllocator_.GetTop(), bpAllocator_.Available()); -} - -void FreeListAllocator::Reset(Heap *heap) -{ - heap_ = heap; - freeList_ = std::make_unique(); - sweeping_ = false; - bpAllocator_.Reset(); -} - -void FreeListAllocator::AddFree(Region *region) -{ - auto begin = region->GetBegin(); - auto end = region->GetEnd(); - Free(begin, end); -} - -uintptr_t FreeListAllocator::Allocate(size_t size) -{ - if (UNLIKELY(size < static_cast(TaggedObject::TaggedObjectSize()))) { - return 0; - } - auto ret = bpAllocator_.Allocate(size); - if (LIKELY(ret != 0)) { - FreeObject::FillFreeObject(heap_->GetEcmaVM(), bpAllocator_.GetTop(), bpAllocator_.Available()); - allocationSizeAccumulator_ += size; - return ret; - } - FreeObject *object = freeList_->Allocator(size); - if (LIKELY(object != nullptr && !object->IsEmpty())) { - return Allocate(object, size); - } - - if (sweeping_) { - // Concurrent sweep maybe sweep same region - heap_->GetSweeper()->FillSweptRegion(type_); - object = freeList_->Allocator(size); - if (LIKELY(object != nullptr && !object->IsEmpty())) { - return Allocate(object, size); - } - - // Parallel - heap_->GetSweeper()->WaitingTaskFinish(type_); - object = freeList_->Allocator(size); - if (LIKELY(object != nullptr && !object->IsEmpty())) { - return Allocate(object, size); - } - } - - return 0; -} - -uintptr_t FreeListAllocator::Allocate(FreeObject *object, size_t size) -{ - FreeBumpPoint(); - bpAllocator_.Reset(object->GetBegin(), object->GetEnd()); - auto ret = bpAllocator_.Allocate(size); - if (ret != 0 && bpAllocator_.Available() > 0) { - FreeObject::FillFreeObject(heap_->GetEcmaVM(), bpAllocator_.GetTop(), bpAllocator_.Available()); - allocationSizeAccumulator_ += size; - } - return ret; -} - -void FreeListAllocator::FreeBumpPoint() -{ - auto begin = bpAllocator_.GetTop(); - auto end = bpAllocator_.GetEnd(); - Free(begin, end); - bpAllocator_.Reset(); -} - -void FreeListAllocator::Free(uintptr_t begin, uintptr_t end, bool isAdd) -{ - ASSERT(heap_ != nullptr); - size_t size = end - begin; - if (size != 0) { - FreeObject::FillFreeObject(heap_->GetEcmaVM(), begin, size); - } - if (UNLIKELY(size < FreeObject::SIZE_OFFSET)) { - return; - } - - freeList_->Free(begin, size, isAdd); -} - -void FreeListAllocator::RebuildFreeList() -{ - bpAllocator_.Reset(); - freeList_->Rebuild(); -} - -void FreeListAllocator::Merge(FreeListAllocator *other) -{ - ASSERT(type_ == other->type_); - other->FreeBumpPoint(); - freeList_->Merge(other->freeList_.get()); -} - -void FreeListAllocator::FillFreeList(FreeObjectKind *kind) -{ - freeList_->AddKind(kind); -} - -size_t FreeListAllocator::GetAvailableSize() const -{ - if (sweeping_) { - heap_->GetSweeper()->WaitingTaskFinish(type_); - } - return freeList_->GetFreeObjectSize(); -} -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_ALLOCATOR_INL_H diff --git a/runtime/mem/allocator.h b/runtime/mem/allocator.h deleted file mode 100644 index 8c9d76e4c0b1ae4939428e9bc116fea053a286ea..0000000000000000000000000000000000000000 --- a/runtime/mem/allocator.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_ALLOCATOR_H -#define ECMASCRIPT_MEM_ALLOCATOR_H - -#include - -#include "plugins/ecmascript/runtime/mem/free_object_list.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/mem.h" - -namespace panda::ecmascript { -class Space; -class Region; -class Heap; - -class Allocator { -public: - Allocator() = default; - virtual ~Allocator() = default; - NO_COPY_SEMANTIC(Allocator); - NO_MOVE_SEMANTIC(Allocator); -}; - -class BumpPointerAllocator : public Allocator { -public: - BumpPointerAllocator() = default; - ~BumpPointerAllocator() override = default; - NO_COPY_SEMANTIC(BumpPointerAllocator); - NO_MOVE_SEMANTIC(BumpPointerAllocator); - - inline explicit BumpPointerAllocator(const Space *space); - inline BumpPointerAllocator(uintptr_t begin, uintptr_t end); - - inline void Reset(); - inline void Reset(const Space *space); - inline void Reset(uintptr_t begin, uintptr_t end); - inline uintptr_t Allocate(size_t size); - - uintptr_t GetTop() const - { - return top_; - } - - uintptr_t GetEnd() const - { - return end_; - } - - void Swap(const BumpPointerAllocator &other) - { - begin_ = other.begin_; - top_ = other.top_; - end_ = other.end_; - } - - size_t Available() const - { - return (end_ - top_); - } - -private: - uintptr_t begin_ {0}; - uintptr_t top_ {0}; - uintptr_t end_ {0}; -}; - -class FreeListAllocator : public Allocator { -public: - FreeListAllocator() = default; - ~FreeListAllocator() override = default; - - NO_COPY_SEMANTIC(FreeListAllocator); - NO_MOVE_SEMANTIC(FreeListAllocator); - - inline explicit FreeListAllocator(const Space *space); - - inline void Reset(const Space *space); - inline void Reset(Heap *heap); - - inline uintptr_t Allocate(size_t size); - inline void AddFree(Region *region); - - inline void RebuildFreeList(); - inline void FillFreeList(FreeObjectKind *kind); - - inline void Swap(FreeListAllocator &other) - { - heap_ = other.heap_; - bpAllocator_.Swap(other.bpAllocator_); - freeList_.swap(other.freeList_); - type_ = other.type_; - sweeping_ = other.sweeping_; - } - - inline void Merge(FreeListAllocator *other); - - inline void FreeBumpPoint(); - - inline void Free(uintptr_t begin, uintptr_t end, bool isAdd = true); - inline void SplitFreeObject(FreeObject *current, size_t allocateSize); - - inline size_t GetAvailableSize() const; - - void SetSweeping(bool sweeping) - { - sweeping_ = sweeping; - } - - size_t GetAllocatedSize() const - { - return allocationSizeAccumulator_; - } - -private: - inline uintptr_t Allocate(FreeObject *object, size_t size); - - BumpPointerAllocator bpAllocator_; - std::unique_ptr freeList_; - Heap *heap_ {nullptr}; - MemSpaceType type_ = OLD_SPACE; - bool sweeping_ = false; - size_t allocationSizeAccumulator_ = 0; -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_ALLOCATOR_H diff --git a/runtime/mem/area.h b/runtime/mem/area.h deleted file mode 100644 index 45eb23930cca4b685e5460fdb12da1bf78b37535..0000000000000000000000000000000000000000 --- a/runtime/mem/area.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_AREA_H -#define ECMASCRIPT_MEM_AREA_H - -namespace panda::ecmascript { -class Area { -public: - Area(uintptr_t begin, size_t capacity) - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - : begin_(begin), end_(begin + capacity) - { - } - ~Area() = default; - NO_COPY_SEMANTIC(Area); - NO_MOVE_SEMANTIC(Area); - - uintptr_t GetBegin() const - { - return begin_; - } - - uintptr_t GetEnd() const - { - return end_; - } - - void LinkPrev(Area *prev) - { - prev_ = prev; - } - - void LinkNext(Area *next) - { - next_ = next; - } - - size_t GetSize() - { - return end_ - begin_; - } - -private: - template - friend class EcmaList; - friend class Worker; - Area *GetPrev() const - { - return prev_; - } - - Area *GetNext() const - { - return next_; - } - uintptr_t begin_; - uintptr_t end_; - Area *next_ {nullptr}; - Area *prev_ {nullptr}; -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_AREA_H diff --git a/runtime/mem/assert_scope-inl.h b/runtime/mem/assert_scope-inl.h deleted file mode 100644 index d2bde54fd11230859f3912baebb35d7a3eefb44e..0000000000000000000000000000000000000000 --- a/runtime/mem/assert_scope-inl.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_ASSERT_SCOPE_INL_H -#define ECMASCRIPT_MEM_ASSERT_SCOPE_INL_H - -#include "assert_scope.h" - -namespace panda::ecmascript { -// Thread-local storage for assert data. Default all asserts to "allow". -// NOLINTNEXTLINE(hicpp-signed-bitwise) -static thread_local size_t currentAssertData(~0); - -template -AssertScopeT::AssertScopeT() : oldData_(currentAssertData) -{ - switch (type) { - case AssertType::GARBAGE_COLLECTION_ASSERT: - currentAssertData = AssertGarbageCollectBit::Update(oldData_.value(), isAllow); - break; - case AssertType::HEAP_ALLOC_ASSERT: - currentAssertData = AssertHeapAllocBit::Update(oldData_.value(), isAllow); - break; - default: - break; - } -} - -template -AssertScopeT::~AssertScopeT() -{ - if (!oldData_.has_value()) { - return; - } - - currentAssertData = oldData_.value(); - oldData_.reset(); -} - -// static -template -bool AssertScopeT::IsAllowed() -{ - switch (type) { - case AssertType::GARBAGE_COLLECTION_ASSERT: - return AssertGarbageCollectBit::Decode(currentAssertData); - case AssertType::HEAP_ALLOC_ASSERT: - return AssertHeapAllocBit::Decode(currentAssertData); - default: - return true; - } -} -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_ASSERT_SCOPE_INL_H \ No newline at end of file diff --git a/runtime/mem/assert_scope.h b/runtime/mem/assert_scope.h deleted file mode 100644 index a999f5c401403228e51b55834e9242dfcbab7beb..0000000000000000000000000000000000000000 --- a/runtime/mem/assert_scope.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_ASSERT_SCOPE_H -#define ECMASCRIPT_MEM_ASSERT_SCOPE_H - -#include - -#include "libpandabase/macros.h" -#include "utils/bit_field.h" - -namespace panda::ecmascript { -using AssertGarbageCollectBit = panda::BitField; -using AssertHeapAllocBit = AssertGarbageCollectBit::NextFlag; - -#ifndef NDEBUG -constexpr bool IS_ALLOW_CHECK = true; -#else -constexpr bool IS_ALLOW_CHECK = false; -#endif - -enum class AssertType : uint8_t { GARBAGE_COLLECTION_ASSERT = 0, HEAP_ALLOC_ASSERT, LAST_ASSERT_TYPE }; - -template -class AssertScopeT { -public: - static bool IsAllowed() - { - return true; - } -}; - -template -class AssertScopeT { -public: - AssertScopeT(); - - ~AssertScopeT(); - - static bool IsAllowed(); - - NO_COPY_SEMANTIC(AssertScopeT); - DEFAULT_NOEXCEPT_MOVE_SEMANTIC(AssertScopeT); - -private: - std::optional oldData_; -}; - -using DisallowGarbageCollection = AssertScopeT; -using AllowGarbageCollection = AssertScopeT; -using DisAllowHeapAlloc = AssertScopeT; -using AllowHeapAlloc = AssertScopeT; - -#if (!defined NDEBUG) || (defined RUN_TEST) -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DISALLOW_GARBAGE_COLLECTION [[maybe_unused]] DisallowGarbageCollection no_gc -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define ALLOW_GARBAGE_COLLECTION [[maybe_unused]] AllowGarbageCollection allow_gc -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DISALLOW_HEAP_ALLOC [[maybe_unused]] DisAllowHeapAlloc no_heap_alloc -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define ALLOW_HEAP_ALLOC [[maybe_unused]] AllowHeapAlloc allow_heap_alloc -#else -#define DISALLOW_GARBAGE_COLLECTION -#define ALLOW_GARBAGE_COLLECTION -#define DISALLOW_HEAP_ALLOC -#define ALLOW_HEAP_ALLOC -#endif - -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define CHECK_NO_GC ASSERT_PRINT(AllowGarbageCollection::IsAllowed(), "disallow execute garbage collection."); - -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define CHECK_NO_HEAP_ALLOC (AllowHeapAlloc::IsAllowed(), "disallow execute heap alloc."); -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_ASSERT_SCOPE_H diff --git a/runtime/mem/barriers-inl.h b/runtime/mem/barriers-inl.h index f28075e02342ff5d5c253bc00d855892cfc85af9..bca2571121142dee108eafa749076e01e63bba4c 100644 --- a/runtime/mem/barriers-inl.h +++ b/runtime/mem/barriers-inl.h @@ -19,48 +19,10 @@ #include "plugins/ecmascript/runtime/js_thread.h" #include "plugins/ecmascript/runtime/mem/barriers.h" #include "plugins/ecmascript/runtime/mem/mem.h" -#include "plugins/ecmascript/runtime/mem/region-inl.h" -#include "plugins/ecmascript/runtime/runtime_api.h" #include "libpandabase/mem/gc_barrier.h" namespace panda::ecmascript { -static inline void MarkingBarrier(uintptr_t slotAddr, Region *objectRegion, TaggedObject *value, Region *valueRegion) -{ - auto heap = valueRegion->GetHeap(); - bool isOnlySemi = heap->IsSemiMarkNeeded(); - if (!JSTaggedValue(value).IsWeak()) { - if (isOnlySemi && !valueRegion->InYoungGeneration()) { - return; - } - auto valueBitmap = valueRegion->GetOrCreateMarkBitmap(); - if (!RuntimeApi::AtomicTestAndSet(valueBitmap, value)) { - RuntimeApi::PushWorkList(heap->GetWorkList(), 0, value, valueRegion); - } - } - if (!isOnlySemi && !objectRegion->InYoungAndCSetGeneration() && valueRegion->InCollectSet()) { - auto set = objectRegion->GetOrCreateCrossRegionRememberedSet(); - RuntimeApi::AtomicInsertCrossRegionRememberedSet(set, slotAddr); - } -} - -static inline void WriteBarrier(void *obj, size_t offset, JSTaggedType value) -{ - ASSERT(value != JSTaggedValue::VALUE_UNDEFINED); - Region *objectRegion = Region::ObjectAddressToRange(static_cast(obj)); - Region *valueRegion = Region::ObjectAddressToRange(reinterpret_cast(value)); - uintptr_t slotAddr = ToUintPtr(obj) + offset; - if (!objectRegion->InYoungGeneration() && valueRegion->InYoungGeneration()) { - // Should align with '8' in 64 and 32 bit platform - ASSERT((slotAddr % static_cast(MemAlignment::MEM_ALIGN_OBJECT)) == 0); - objectRegion->InsertOldToNewRememberedSet(slotAddr); - } - - if (valueRegion->IsMarking()) { - MarkingBarrier(slotAddr, objectRegion, reinterpret_cast(value), valueRegion); - } -} - /* static */ template inline T Barriers::GetDynValue(const void *obj, size_t offset) diff --git a/runtime/mem/barriers.h b/runtime/mem/barriers.h index cd1f3cd6bff3010d8d1f47543ec30d1974a5ab5c..746a2a3d919db3d6bed9ec263bbd69439d4768a0 100644 --- a/runtime/mem/barriers.h +++ b/runtime/mem/barriers.h @@ -16,8 +16,6 @@ #ifndef ECMASCRIPT_MEM_BARRIERS_H #define ECMASCRIPT_MEM_BARRIERS_H -#include "plugins/ecmascript/runtime/mem/mark_word.h" - namespace panda::ecmascript { class Barriers { public: diff --git a/runtime/mem/c_containers.h b/runtime/mem/c_containers.h deleted file mode 100644 index 3d1ff7cc62bcbeb03a2fa25299fbed97d62cbe28..0000000000000000000000000000000000000000 --- a/runtime/mem/c_containers.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_C_CONTAINERS_H -#define ECMASCRIPT_MEM_C_CONTAINERS_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "plugins/ecmascript/runtime/mem/caddress_allocator.h" - -namespace panda::ecmascript { -template -using CVector = std::vector>; - -template -using CList = std::list>; - -template > -using CMap = std::map>>; - -template > -using CMultiMap = std::multimap>>; - -template , class KeyEqual = std::equal_to> -using CUnorderedMultiMap = - std::unordered_multimap>>; - -template -using CDeque = std::deque>; - -template > -using CQueue = std::queue; - -template , class KeyEqual = std::equal_to> -using CUnorderedMap = std::unordered_map>>; - -template , class KeyEqual = std::equal_to> -using CUnorderedSet = std::unordered_set>; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_C_CONTAINERS_H diff --git a/runtime/mem/caddress_allocator.h b/runtime/mem/caddress_allocator.h deleted file mode 100644 index dfecd6292aa37c2afa0d1b1ec0e3e3dc77253a80..0000000000000000000000000000000000000000 --- a/runtime/mem/caddress_allocator.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef RUNTIME_ECMASCRIPT_C_ADDRESS_ALLOCATOR_H -#define RUNTIME_ECMASCRIPT_C_ADDRESS_ALLOCATOR_H - -#include "plugins/ecmascript/runtime/mem/chunk.h" - -namespace panda::ecmascript { -template -class CAddressAllocator { -public: - // using by std allocator - using value_type = T; - using pointer = T *; - using reference = T &; - using const_pointer = const T *; - using const_reference = const T &; - using size_type = size_t; - using difference_type = ptrdiff_t; - - template - struct Rebind { - using other = CAddressAllocator; - }; - - template - using rebind = Rebind; - - CAddressAllocator() = default; - - template - explicit CAddressAllocator(const CAddressAllocator &other [[maybe_unused]]) - { - } - - CAddressAllocator(const CAddressAllocator &) = default; - CAddressAllocator &operator=(const CAddressAllocator &) = default; - CAddressAllocator(CAddressAllocator &&other) noexcept = default; - CAddressAllocator &operator=(CAddressAllocator &&other) noexcept = default; - ~CAddressAllocator() = default; - - // NOLINTNEXTLINE(readability-identifier-naming) - size_type max_size() const - { - return static_cast(-1) / sizeof(T); - } - - bool operator==([[maybe_unused]] CAddressAllocator const &other) const - { - return false; - } - - bool operator!=([[maybe_unused]] CAddressAllocator const &other) const - { - return true; - } - - // NOLINTNEXTLINE(readability-identifier-naming) - pointer allocate(size_type n, [[maybe_unused]] const void *ptr = nullptr) - { - ASSERT(n <= max_size()); - return static_cast(Allocate(n * sizeof(T))); - } - - // NOLINTNEXTLINE(readability-identifier-naming) - void deallocate([[maybe_unused]] pointer p, [[maybe_unused]] size_type n) - { - Free(static_cast(p)); - } - - template - void construct(U *p, Args &&...args) // NOLINT(readability-identifier-naming) - { - if (p == nullptr) { - return; - } - ::new (static_cast(p)) U(std::forward(args)...); - } - template - void destroy(U *p) // NOLINT(readability-identifier-naming) - { - if (p == nullptr) { - return; - } - p->~U(); - } - - [[nodiscard]] void *Allocate(size_t size) - { - if (size == 0) { - LOG_ECMA_MEM(FATAL) << "size must have a size bigger than 0"; - UNREACHABLE(); - } - // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) - void *ptr = malloc(size); - if (ptr == nullptr) { - LOG_ECMA_MEM(FATAL) << "malloc failed"; - UNREACHABLE(); - } - return ptr; - } - - template - [[nodiscard]] S *New(Args &&...args) - { - auto p = reinterpret_cast(Allocate(sizeof(S))); - new (p) S(std::forward(args)...); - return reinterpret_cast(p); - } - - template - void Finalize(S *ptr) - { - ASSERT(ptr != nullptr); - // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) - if constexpr (std::is_class_v) { - ptr->~S(); - } - Free(ptr); - } - - [[nodiscard]] T *AllocArray(size_t size) - { - return static_cast(Allocate(size * sizeof(T))); - } - - void Delete(T *ptr) - { - if (ptr == nullptr) { - return; - } - // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) - if constexpr (std::is_class_v) { - ptr->~T(); - } - Free(ptr); - } - - void Free(void *mem) - { - if (mem == nullptr) { - return; - } - // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) - free(mem); - } -}; -} // namespace panda::ecmascript - -#endif // RUNTIME_ECMASCRIPT_C_ADDRESS_ALLOCATOR_H diff --git a/runtime/mem/chunk.cpp b/runtime/mem/chunk.cpp deleted file mode 100644 index 94553801e14161723a91ece3021bc6c4e2df5644..0000000000000000000000000000000000000000 --- a/runtime/mem/chunk.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/chunk.h" - -#include "plugins/ecmascript/runtime/mem/heap.h" - -namespace panda::ecmascript { -Chunk::Chunk(RegionFactory *factory) : factory_(factory) {} - -Area *Chunk::NewArea(size_t size) -{ - auto area = factory_->AllocateArea(size); - if (area == nullptr) { - LOG_ECMA_MEM(FATAL) << "OOM Chunk::NewArea area is nullptr"; - UNREACHABLE(); - } - areaList_.AddNode(area); - currentArea_ = area; - return area; -} - -uintptr_t Chunk::Expand(size_t size) -{ - ASSERT(end_ - ptr_ < size); - - Area *head = currentArea_; - size_t newSize; - if (head != nullptr) { - // NOLINTNEXTLINE(hicpp-signed-bitwise) - newSize = size + (head->GetSize() << 1); - } else { - newSize = sizeof(Area) + MEM_ALIGN + size; - } - - if (newSize < MIN_CHUNK_AREA_SIZE) { - newSize = MIN_CHUNK_AREA_SIZE; - } else if (newSize > MAX_CHUNK_AREA_SIZE) { - size_t minNewSize = sizeof(Area) + MEM_ALIGN + size; - newSize = std::max(minNewSize, MAX_CHUNK_AREA_SIZE); - } - - if (newSize > static_cast(std::numeric_limits::max())) { - LOG_ECMA_MEM(FATAL) << "OOM chunk"; - UNREACHABLE(); - } - - Area *area = NewArea(newSize); - if (area == nullptr) { - LOG_ECMA_MEM(FATAL) << "OOM chunk"; - UNREACHABLE(); - } - uintptr_t result = AlignUp(area->GetBegin(), MEM_ALIGN); - ptr_ = result + size; - end_ = area->GetEnd(); - return result; -} - -void Chunk::ReleaseMemory() -{ - while (!areaList_.IsEmpty()) { - Area *node = areaList_.PopBack(); - factory_->FreeArea(node); - } - ptr_ = 0; - end_ = 0; -} -} // namespace panda::ecmascript diff --git a/runtime/mem/chunk.h b/runtime/mem/chunk.h deleted file mode 100644 index 434451ca865a575e4df08959c8b34f1759f4aa23..0000000000000000000000000000000000000000 --- a/runtime/mem/chunk.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef RUNTIME_ECMASCRIPT_CHUNK_H -#define RUNTIME_ECMASCRIPT_CHUNK_H - -#include "plugins/ecmascript/runtime/mem/ecma_list.h" -#include "plugins/ecmascript/runtime/mem/area.h" - -namespace panda::ecmascript { -class RegionFactory; - -class Chunk { -public: - static constexpr size_t MEM_ALIGN = 8U; - - explicit Chunk(RegionFactory *factory); - ~Chunk() - { - ReleaseMemory(); - } - - NO_COPY_SEMANTIC(Chunk); - NO_MOVE_SEMANTIC(Chunk); - - [[nodiscard]] void *Allocate(size_t size) - { - if (size == 0) { - LOG_ECMA_MEM(FATAL) << "size must have a size bigger than 0"; - UNREACHABLE(); - } - uintptr_t result = ptr_; - size = AlignUp(size, MEM_ALIGN); - if (UNLIKELY(size > end_ - ptr_)) { - result = Expand(size); - } else { - ptr_ += size; - } - - return reinterpret_cast(result); - } - - template - [[nodiscard]] T *NewArray(size_t size) - { - return static_cast(Allocate(size * sizeof(T))); - } - - template - [[nodiscard]] T *New(Args &&...args) - { - auto p = reinterpret_cast(Allocate(sizeof(T))); - new (p) T(std::forward(args)...); - return reinterpret_cast(p); - } - - template - void Delete(T *ptr) - { - ASSERT(ptr != nullptr); - // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) - if constexpr (std::is_class_v) { - ptr->~T(); - } - Free(ptr); - } - - void Free([[maybe_unused]] void *mem) - { - // do nothing - } - -private: - uintptr_t Expand(size_t size); - Area *NewArea(size_t size); - void ReleaseMemory(); - - uintptr_t ptr_ {0}; - uintptr_t end_ {0}; - - Area *currentArea_ {nullptr}; - EcmaList areaList_ {}; - RegionFactory *factory_ {nullptr}; -}; -} // namespace panda::ecmascript - -#endif // RUNTIME_ECMASCRIPT_CHUNK_H diff --git a/runtime/mem/chunk_allocator.h b/runtime/mem/chunk_allocator.h deleted file mode 100644 index 9ff36a147f1bdf6e047a477230cde1e0845e9452..0000000000000000000000000000000000000000 --- a/runtime/mem/chunk_allocator.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef RUNTIME_ECMASCRIPT_CHUNK_ALLOCATOR_H -#define RUNTIME_ECMASCRIPT_CHUNK_ALLOCATOR_H - -#include "plugins/ecmascript/runtime/mem/chunk.h" - -namespace panda::ecmascript { -template -class ChunkAllocator { -public: - // used for std allocator - using value_type = T; - using pointer = T *; - using reference = T &; - using const_pointer = const T *; - using const_reference = const T &; - using size_type = size_t; - using difference_type = ptrdiff_t; - - template - struct Rebind { - using other = ChunkAllocator; - }; - - template - using rebind = Rebind; - - explicit ChunkAllocator(Chunk *chunk) : chunk_(chunk) {} - - template - explicit ChunkAllocator(const ChunkAllocator &other) : chunk_(other.chunk_) - { - } - template - friend class ChunkAllocator; - - ChunkAllocator(const ChunkAllocator &) = default; - ChunkAllocator &operator=(const ChunkAllocator &) = default; - ChunkAllocator(ChunkAllocator &&other) noexcept - { - chunk_ = other.chunk_; - other.chunk_ = nullptr; - } - ChunkAllocator &operator=(ChunkAllocator &&other) noexcept - { - chunk_ = other.chunk_; - other.chunk_ = nullptr; - return *this; - } - ~ChunkAllocator() = default; - - // NOLINTNEXTLINE(readability-identifier-naming) - size_type max_size() const - { - return static_cast(-1) / sizeof(T); - } - - // NOLINTNEXTLINE(readability-identifier-naming) - pointer address(reference x) const - { - return &x; - } - // NOLINTNEXTLINE(readability-identifier-naming) - const_pointer address(const_reference x) const - { - return &x; - } - - // NOLINTNEXTLINE(readability-identifier-naming) - pointer allocate(size_type n, [[maybe_unused]] const void *ptr = nullptr) - { - ASSERT(n <= max_size()); - return chunk_->NewArray(n); - } - - // NOLINTNEXTLINE(readability-identifier-naming) - void deallocate([[maybe_unused]] pointer p, [[maybe_unused]] size_type n) {} - - template - void construct(U *p, Args &&...args) // NOLINT(readability-identifier-naming) - { - ::new (static_cast(p)) U(std::forward(args)...); - } - template - void destroy(U *p) // NOLINT(readability-identifier-naming) - { - if (p == nullptr) { - return; - } - p->~U(); - } - - bool operator==(ChunkAllocator const &other) const - { - return chunk_ == other.chunk_; - } - bool operator!=(ChunkAllocator const &other) const - { - return chunk_ != other.chunk_; - } - - [[nodiscard]] void *Alloc(size_t size) - { - return chunk_->NewArray(size); - } - - [[nodiscard]] T *AllocArray(size_t size) - { - return chunk_->NewArray(size); - } - - void Delete(T *ptr) - { - if (ptr == nullptr) { - LOG_ECMA_MEM(FATAL) << "free nullptr"; - UNREACHABLE(); - } - // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) - if constexpr (std::is_class_v) { - ptr->~T(); - } - Free(ptr); - } - - void Free([[maybe_unused]] void *mem) {} - - Chunk *chunk() - { - return chunk_; - } - -private: - Chunk *chunk_; -}; -} // namespace panda::ecmascript - -#endif // RUNTIME_ECMASCRIPT_CHUNK_ALLOCATOR_H diff --git a/runtime/mem/chunk_containers.h b/runtime/mem/chunk_containers.h deleted file mode 100644 index d5b39e8dc98aa1b38b5c442db3f428bdc0af301d..0000000000000000000000000000000000000000 --- a/runtime/mem/chunk_containers.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LIBPANDABASE_ECMASCRIPT_MEM_CONTAINERS_H -#define LIBPANDABASE_ECMASCRIPT_MEM_CONTAINERS_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "plugins/ecmascript/runtime/mem/chunk_allocator.h" - -namespace panda::ecmascript { -template -class ChunkVector : public std::vector> { -public: - explicit ChunkVector(Chunk *chunk) : std::vector>(ChunkAllocator(chunk)) {} - - ChunkVector(size_t size, Chunk *chunk) : std::vector>(size, T(), ChunkAllocator(chunk)) {} - - ChunkVector(size_t size, T def, Chunk *chunk) - : std::vector>(size, def, ChunkAllocator(chunk)) - { - } - ~ChunkVector() = default; - NO_COPY_SEMANTIC(ChunkVector); - NO_MOVE_SEMANTIC(ChunkVector); -}; - -template > -class ChunkMap : public std::map>> { -public: - // Constructs an empty map. - explicit ChunkMap(Chunk *chunk) - : std::map>>(Compare(), - ChunkAllocator>(chunk)) - { - } - ~ChunkMap() = default; - NO_COPY_SEMANTIC(ChunkMap); - NO_MOVE_SEMANTIC(ChunkMap); -}; - -template , typename KeyEqual = std::equal_to> -class ChunkUnorderedMap : public std::unordered_map>> { -public: - // NOLINTNEXTLINE(readability-magic-numbers) - explicit ChunkUnorderedMap(Chunk *chunk, size_t bucket_count = 100) - : std::unordered_map>>( - bucket_count, Hash(), KeyEqual(), ChunkAllocator>(chunk)) - { - } - ~ChunkUnorderedMap() = default; - NO_COPY_SEMANTIC(ChunkUnorderedMap); - NO_MOVE_SEMANTIC(ChunkUnorderedMap); -}; - -template > -class ChunkMultimap : public std::multimap>> { -public: - // Constructs an empty multimap. - explicit ChunkMultimap(Chunk *chunk) - : std::multimap>>( - Compare(), ChunkAllocator>(chunk)) - { - } - ~ChunkMultimap() = default; - NO_COPY_SEMANTIC(ChunkMultimap); - NO_MOVE_SEMANTIC(ChunkMultimap); -}; -} // namespace panda::ecmascript - -#endif // LIBPANDABASE_ECMASCRIPT_MEM_CONTAINERS_H diff --git a/runtime/mem/clock_scope.h b/runtime/mem/clock_scope.h deleted file mode 100644 index ce0a328373770402512a52626e588d0926ef8e16..0000000000000000000000000000000000000000 --- a/runtime/mem/clock_scope.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_CLOCK_SCOPE_H -#define ECMASCRIPT_MEM_CLOCK_SCOPE_H - -#include -#include "chrono" -#include "libpandabase/utils/logger.h" - -namespace panda::ecmascript { -class ClockScope { - using Clock = std::chrono::high_resolution_clock; - using Duration = std::chrono::duration; - -public: - explicit ClockScope() - { - start_ = Clock::now(); - } - - ~ClockScope() = default; - - Duration GetPauseTime() const - { - return Clock::now() - start_; - } - - float TotalSpentTime() const - { - auto duration = std::chrono::duration_cast(Clock::now() - start_); - return static_cast(duration.count()) / MILLION_TIME; - } - -private: - NO_COPY_SEMANTIC(ClockScope); - NO_MOVE_SEMANTIC(ClockScope); - - Clock::time_point start_; - static constexpr uint32_t MILLION_TIME = 1000; -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_CLOCK_SCOPE_H diff --git a/runtime/mem/compress_collector.cpp b/runtime/mem/compress_collector.cpp deleted file mode 100644 index 1c3c89972a4452ffdb3b7f62a2ec60701b0ae313..0000000000000000000000000000000000000000 --- a/runtime/mem/compress_collector.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/compress_collector.h" - -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/mem/clock_scope.h" -#include "plugins/ecmascript/runtime/mem/concurrent_marker.h" -#include "plugins/ecmascript/runtime/mem/mem_manager.h" -#include "plugins/ecmascript/runtime/mem/object_xray-inl.h" -#include "plugins/ecmascript/runtime/mem/mark_stack.h" -#include "plugins/ecmascript/runtime/mem/mem.h" -#include "plugins/ecmascript/runtime/mem/parallel_marker-inl.h" -#include "plugins/ecmascript/runtime/mem/space-inl.h" -#include "plugins/ecmascript/runtime/runtime_call_id.h" -#include "plugins/ecmascript/runtime/vmstat/runtime_stat.h" - -namespace panda::ecmascript { -CompressCollector::CompressCollector(Heap *heap) : heap_(heap), workList_(heap->GetWorkList()) {} - -void CompressCollector::RunPhases() -{ - ecmascript::JSThread *thread = heap_->GetEcmaVM()->GetJSThread(); - INTERPRETER_TRACE(thread, CompressCollector_RunPhases); - ClockScope clockScope; - - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "CompressCollector::RunPhases"); - bool concurrentMark = heap_->CheckConcurrentMark(thread); - if (concurrentMark) { - ECMA_GC_LOG() << "CompressCollector after ConcurrentMarking"; - heap_->GetConcurrentMarker()->Reset(); // HPPGC use mark result to move TaggedObject. - } - InitializePhase(); - MarkingPhase(); - SweepPhases(); - FinishPhase(); - heap_->GetEcmaVM()->GetEcmaGCStats()->StatisticCompressCollector(clockScope.GetPauseTime(), youngAndOldAliveSize_, - youngSpaceCommitSize_, oldSpaceCommitSize_, - nonMoveSpaceFreeSize_, nonMoveSpaceCommitSize_); - ECMA_GC_LOG() << "CompressCollector::RunPhases " << clockScope.TotalSpentTime(); -} - -void CompressCollector::InitializePhase() -{ - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "CompressCollector::InitializePhase"); - heap_->Prepare(); - auto callback = [](Region *current) { - // ensure mark bitmap - auto bitmap = current->GetMarkBitmap(); - if (bitmap == nullptr) { - current->GetOrCreateMarkBitmap(); - } else { - bitmap->ClearAllBits(); - } - auto rememberset = current->GetOldToNewRememberedSet(); - if (rememberset != nullptr) { - rememberset->ClearAllBits(); - } - }; - heap_->EnumerateNonMovableRegions(callback); - workList_->Initialize(TriggerGCType::COMPRESS_FULL_GC, ParallelGCTaskPhase::COMPRESS_HANDLE_GLOBAL_POOL_TASK); - heap_->GetCompressGcMarker()->Initialized(); - heap_->GetEvacuationAllocator()->Initialize(TriggerGCType::COMPRESS_FULL_GC); - - youngAndOldAliveSize_ = 0; - nonMoveSpaceFreeSize_ = 0; - youngSpaceCommitSize_ = heap_->GetFromSpace()->GetCommittedSize(); - oldSpaceCommitSize_ = heap_->GetCompressSpace()->GetCommittedSize(); - nonMoveSpaceCommitSize_ = heap_->GetNonMovableSpace()->GetCommittedSize(); -} - -void CompressCollector::MarkingPhase() -{ - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "CompressCollector::MarkingPhase"); - heap_->GetCompressGcMarker()->MarkRoots(0); - heap_->GetCompressGcMarker()->ProcessMarkStack(0); - heap_->WaitRunningTaskFinished(); -} - -void CompressCollector::SweepPhases() -{ - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "CompressCollector::SweepPhases"); - // process weak reference - auto totalThreadCount = Platform::GetCurrentPlatform()->GetTotalThreadNum() + 1; // gc thread and main thread - for (uint32_t i = 0; i < totalThreadCount; i++) { - ProcessQueue *queue = workList_->GetWeakReferenceQueue(i); - - while (true) { - auto obj = queue->PopBack(); - if (UNLIKELY(obj == nullptr)) { - break; - } - ObjectSlot slot(ToUintPtr(obj)); - JSTaggedValue value(slot.GetTaggedType()); - auto header = value.GetTaggedWeakRef(); - - Region *objectRegion = Region::ObjectAddressToRange(header); - if (!objectRegion->InYoungAndOldGeneration()) { - auto markBitmap = objectRegion->GetMarkBitmap(); - if (!markBitmap->Test(header)) { - slot.Update(static_cast(JSTaggedValue::Undefined().GetRawData())); - } - } else { - MarkWord markWord(header); - if (markWord.IsForwardingAddress()) { - TaggedObject *dst = markWord.ToForwardingAddress(); - auto weakRef = JSTaggedValue(JSTaggedValue(dst).CreateAndGetWeakRef()).GetRawTaggedObject(); - slot.Update(weakRef); - } else { - slot.Update(static_cast(JSTaggedValue::Undefined().GetRawData())); - } - } - } - } - - auto stringTable = heap_->GetEcmaVM()->GetEcmaStringTable(); - WeakRootVisitor gcUpdateWeak = [](TaggedObject *header) { - Region *objectRegion = Region::ObjectAddressToRange(header); - if (!objectRegion->InYoungAndOldGeneration()) { - auto markBitmap = objectRegion->GetMarkBitmap(); - if (markBitmap->Test(header)) { - return header; - } - return reinterpret_cast(ToUintPtr(nullptr)); - } - - MarkWord markWord(header); - if (markWord.IsForwardingAddress()) { - return markWord.ToForwardingAddress(); - } - return reinterpret_cast(ToUintPtr(nullptr)); - }; - stringTable->SweepWeakReference(gcUpdateWeak); - heap_->GetEcmaVM()->GetJSThread()->IterateWeakEcmaGlobalStorage(gcUpdateWeak); - heap_->GetEcmaVM()->ProcessReferences(gcUpdateWeak); - - heap_->UpdateDerivedObjectInStack(); - heap_->GetSweeper()->SweepPhases(true); -} - -void CompressCollector::FinishPhase() -{ - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "CompressCollector::FinishPhase"); - workList_->Finish(youngAndOldAliveSize_); - heap_->GetEvacuationAllocator()->Finalize(TriggerGCType::COMPRESS_FULL_GC); -} -} // namespace panda::ecmascript diff --git a/runtime/mem/compress_collector.h b/runtime/mem/compress_collector.h deleted file mode 100644 index fa44094c2653b796f37a1589afcc3763adabb0c0..0000000000000000000000000000000000000000 --- a/runtime/mem/compress_collector.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_COMPRESS_COLLECTOR_H -#define ECMASCRIPT_MEM_COMPRESS_COLLECTOR_H - -#include "plugins/ecmascript/runtime/mem/parallel_work_helper.h" -#include "plugins/ecmascript/runtime/mem/semi_space_collector.h" - -namespace panda::ecmascript { -class Heap; -class JSHClass; - -class CompressCollector : public GarbageCollector { -public: - explicit CompressCollector(Heap *heap); - ~CompressCollector() override = default; - - NO_COPY_SEMANTIC(CompressCollector); - NO_MOVE_SEMANTIC(CompressCollector); - - void RunPhases(); - -private: - void InitializePhase(); - void MarkingPhase(); - void SweepPhases(); - void FinishPhase(); - - Heap *heap_; - size_t youngAndOldAliveSize_ = 0; - size_t nonMoveSpaceFreeSize_ = 0; - size_t youngSpaceCommitSize_ = 0; - size_t oldSpaceCommitSize_ = 0; - size_t nonMoveSpaceCommitSize_ = 0; - - // obtain from heap - WorkerHelper *workList_ {nullptr}; - - friend class WorkerHelper; - friend class Heap; -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_COMPRESS_COLLECTOR_H diff --git a/runtime/mem/concurrent_marker.cpp b/runtime/mem/concurrent_marker.cpp deleted file mode 100644 index 9518c28716cfb5f6a13f50bce137bec91afbeecb..0000000000000000000000000000000000000000 --- a/runtime/mem/concurrent_marker.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/concurrent_marker.h" - -#include "plugins/ecmascript/runtime/mem/allocator-inl.h" -#include "plugins/ecmascript/runtime/mem/clock_scope.h" -#include "plugins/ecmascript/runtime/mem/heap-inl.h" -#include "plugins/ecmascript/runtime/mem/object_xray-inl.h" -#include "plugins/ecmascript/runtime/mem/mark_word.h" -#include "plugins/ecmascript/runtime/mem/parallel_marker-inl.h" -#include "plugins/ecmascript/runtime/mem/space-inl.h" -#include "plugins/ecmascript/runtime/mem/verification.h" -#include "plugins/ecmascript/runtime/platform/platform.h" -#include "os/mutex.h" - -namespace panda::ecmascript { -ConcurrentMarker::ConcurrentMarker(Heap *heap) - : heap_(heap), vm_(heap->GetEcmaVM()), thread_(vm_->GetJSThread()), workList_(heap->GetWorkList()) -{ -} - -void ConcurrentMarker::ConcurrentMarking() -{ - ECMA_GC_LOG() << "ConcurrentMarker: Concurrent Mark Begin"; - - heap_->Prepare(); - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "ConcurrentMarker::ConcurrentMarking"); - thread_->SetMarkStatus(MarkStatus::MARKING); - if (!heap_->IsSemiMarkNeeded()) { - heapObjectSize_ = heap_->GetHeapObjectSize(); - if (heap_->GetSweeper()->CanSelectCset()) { - const_cast(heap_->GetOldSpace())->SelectCSet(); - } - } else { - heapObjectSize_ = heap_->GetNewSpace()->GetHeapObjectSize(); - } - - InitializeMarking(); - Platform::GetCurrentPlatform()->PostTask(std::make_unique(heap_)); - if (heap_->IsSemiMarkNeeded() && heap_->IsParallelGCEnabled()) { - heap_->PostParallelGCTask(ParallelGCTaskPhase::CONCURRENT_HANDLE_OLD_TO_NEW_TASK); - } -} - -void ConcurrentMarker::FinishPhase() -{ - size_t aliveSize = 0; - workList_->Finish(aliveSize); -} - -void ConcurrentMarker::ReMarking() -{ - ECMA_GC_LOG() << "ConcurrentMarker: Remarking Begin"; - Marker *nonMoveMarker = heap_->GetNonMovableMarker(); - nonMoveMarker->MarkRoots(0); - if (heap_->IsSemiMarkNeeded() && !heap_->IsParallelGCEnabled()) { - heap_->GetNonMovableMarker()->ProcessOldToNew(0); - } else { - nonMoveMarker->ProcessMarkStack(0); - } - heap_->WaitRunningTaskFinished(); -} - -void ConcurrentMarker::HandleMarkFinished() // js-thread wait for sweep -{ - os::memory::LockHolder lock(waitMarkingFinishedMutex_); - if (notifyMarkingFinished_) { - heap_->CollectGarbage(TriggerGCType::OLD_GC); - } -} - -void ConcurrentMarker::WaitConcurrentMarkingFinished() // call in EcmaVm thread, wait for mark finished -{ - os::memory::LockHolder lock(waitMarkingFinishedMutex_); - if (!notifyMarkingFinished_) { - vmThreadWaitMarkingFinished_ = true; - waitMarkingFinishedCV_.Wait(&waitMarkingFinishedMutex_); - } -} - -void ConcurrentMarker::Reset(bool isClearCSet) -{ - FinishPhase(); - thread_->SetMarkStatus(MarkStatus::READY_TO_MARK); - notifyMarkingFinished_ = false; - duration_ = 0.0; - if (isClearCSet) { - // Mix space gc clear cset when evacuation allocator finalize - const_cast(heap_->GetOldSpace())->ClearRegionFromCSet(); - } - heap_->EnumerateRegions([](Region *current) { - current->SetMarking(false); - current->ClearFlag(RegionFlags::IS_IN_PROMOTE_SET); - }); -} - -// -------------------- privete method ------------------------------------------ -void ConcurrentMarker::InitializeMarking() -{ - heap_->EnumerateRegions([](Region *region) { - // ensure mark bitmap - auto markBitmap = region->GetMarkBitmap(); - if (markBitmap == nullptr) { - region->GetOrCreateMarkBitmap(); - } else { - markBitmap->ClearAllBits(); - } - auto rememberset = region->GetCrossRegionRememberedSet(); - if (rememberset != nullptr) { - rememberset->ClearAllBits(); - } - region->SetMarking(true); - }); - if (heap_->IsSemiMarkNeeded()) { - heap_->EnumerateNewSpaceRegions([](Region *current) { current->ResetAliveObject(); }); - } else { - heap_->EnumerateRegions([](Region *current) { current->ResetAliveObject(); }); - } - workList_->Initialize(TriggerGCType::OLD_GC, ParallelGCTaskPhase::CONCURRENT_HANDLE_GLOBAL_POOL_TASK); - heap_->GetNonMovableMarker()->MarkRoots(0); -} - -bool ConcurrentMarker::MarkerTask::Run(uint32_t threadId) -{ - ClockScope clockScope; - heap_->GetNonMovableMarker()->ProcessMarkStack(threadId); - heap_->WaitRunningTaskFinished(); - heap_->GetConcurrentMarker()->MarkingFinished(); - heap_->GetConcurrentMarker()->SetDuration(clockScope.TotalSpentTime()); - return true; -} - -void ConcurrentMarker::MarkingFinished() -{ - os::memory::LockHolder lock(waitMarkingFinishedMutex_); - thread_->SetMarkStatus(MarkStatus::MARK_FINISHED); - if (vmThreadWaitMarkingFinished_) { - vmThreadWaitMarkingFinished_ = false; - waitMarkingFinishedCV_.Signal(); - } - notifyMarkingFinished_ = true; -} -} // namespace panda::ecmascript diff --git a/runtime/mem/concurrent_marker.h b/runtime/mem/concurrent_marker.h deleted file mode 100644 index cc5283a26ce68e745a448b232902d745878361df..0000000000000000000000000000000000000000 --- a/runtime/mem/concurrent_marker.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_CONCURRENT_MARKER_H -#define ECMASCRIPT_MEM_CONCURRENT_MARKER_H - -#include -#include - -#include "plugins/ecmascript/runtime/mem/object_xray.h" -#include "plugins/ecmascript/runtime/mem/parallel_work_helper.h" -#include "plugins/ecmascript/runtime/mem/space.h" -#include "plugins/ecmascript/runtime/platform/task.h" - -#include "os/mutex.h" - -namespace panda::ecmascript { -class Heap; - -class ConcurrentMarker { -public: - explicit ConcurrentMarker(Heap *heap); - ~ConcurrentMarker() = default; - - void ConcurrentMarking(); - void FinishPhase(); - void ReMarking(); - - void HandleMarkFinished(); // call in vm thread. - void WaitConcurrentMarkingFinished(); // call in main thread - void Reset(bool isClearCSet = true); - - double GetDuration() const - { - return duration_; - } - - double GetHeapObjectSize() const - { - return heapObjectSize_; - } - -private: - NO_COPY_SEMANTIC(ConcurrentMarker); - NO_MOVE_SEMANTIC(ConcurrentMarker); - - class MarkerTask : public Task { - public: - explicit MarkerTask(Heap *heap) : heap_(heap) {} - ~MarkerTask() override = default; - bool Run(uint32_t threadId) override; - - private: - NO_COPY_SEMANTIC(MarkerTask); - NO_MOVE_SEMANTIC(MarkerTask); - - Heap *heap_ {nullptr}; - }; - - void SetDuration(double duration) - { - duration_ = duration; - } - - void InitializeMarking(); - void MarkingFinished(); - - Heap *heap_ {nullptr}; - EcmaVM *vm_ {nullptr}; - JSThread *thread_ {nullptr}; - - // obtain from heap - WorkerHelper *workList_ {nullptr}; - size_t heapObjectSize_ {0}; - double duration_ {0.0}; - - bool notifyMarkingFinished_ {false}; // notify js-thread that marking is finished and need sweep - bool vmThreadWaitMarkingFinished_ {false}; // jsMainThread waiting for concurrentGC FINISHED - os::memory::Mutex waitMarkingFinishedMutex_; - os::memory::ConditionVariable waitMarkingFinishedCV_; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_CONCURRENT_MARKER_H diff --git a/runtime/mem/concurrent_sweeper.cpp b/runtime/mem/concurrent_sweeper.cpp deleted file mode 100644 index 33ad87c970016edc431468ad7347e07208a8bdff..0000000000000000000000000000000000000000 --- a/runtime/mem/concurrent_sweeper.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/concurrent_sweeper.h" - -#include "plugins/ecmascript/runtime/js_hclass-inl.h" -#include "plugins/ecmascript/runtime/mem/allocator-inl.h" -#include "plugins/ecmascript/runtime/mem/free_object_list.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/mem_manager.h" -#include "plugins/ecmascript/runtime/mem/space-inl.h" -#include "plugins/ecmascript/runtime/platform/platform.h" - -namespace panda::ecmascript { -ConcurrentSweeper::ConcurrentSweeper(Heap *heap, bool concurrentSweep) : heap_(heap), concurrentSweep_(concurrentSweep) -{ -} - -void ConcurrentSweeper::SweepPhases(bool compressGC) -{ - if (concurrentSweep_) { - // Add all region to region list. Ensure all task finish - if (!compressGC) { - heap_->GetOldSpace()->EnumerateNonCollectRegionSet( - [this](Region *current) { AddRegion(OLD_SPACE, current); }); - } - heap_->GetNonMovableSpace()->EnumerateRegions([this](Region *current) { AddRegion(NON_MOVABLE, current); }); - heap_->GetMachineCodeSpace()->EnumerateRegions( - [this](Region *current) { AddRegion(MACHINE_CODE_SPACE, current); }); - - // Prepare - isSweeping_ = true; - startSpaceType_ = compressGC ? NON_MOVABLE : OLD_SPACE; - for (int type = startSpaceType_; type < FREE_LIST_NUM; type++) { - auto spaceType = static_cast(type); - FreeListAllocator &allocator = heap_->GetHeapManager()->GetFreeListAllocator(spaceType); - remainderTaskNum_[type] = FREE_LIST_NUM - startSpaceType_; - allocator.SetSweeping(true); - allocator.RebuildFreeList(); - } - - if (!compressGC) { - Platform::GetCurrentPlatform()->PostTask(std::make_unique(this, OLD_SPACE)); - canSelectCset_ = true; - } else { - canSelectCset_ = false; - } - Platform::GetCurrentPlatform()->PostTask(std::make_unique(this, NON_MOVABLE)); - Platform::GetCurrentPlatform()->PostTask(std::make_unique(this, MACHINE_CODE_SPACE)); - } else { - if (!compressGC) { - SweepSpace(OLD_SPACE, const_cast(heap_->GetOldSpace()), - heap_->GetHeapManager()->GetOldSpaceAllocator()); - canSelectCset_ = true; - } else { - canSelectCset_ = false; - } - SweepSpace(NON_MOVABLE, const_cast(heap_->GetNonMovableSpace()), - heap_->GetHeapManager()->GetNonMovableSpaceAllocator()); - SweepSpace(MACHINE_CODE_SPACE, const_cast(heap_->GetMachineCodeSpace()), - heap_->GetHeapManager()->GetMachineCodeSpaceAllocator()); - } - SweepHugeSpace(); -} - -void ConcurrentSweeper::SweepSpace(MemSpaceType type, bool isMain) -{ - FreeListAllocator &allocator = heap_->GetHeapManager()->GetFreeListAllocator(type); - Region *current = GetRegionSafe(type); - while (current != nullptr) { - FreeRegion(current, allocator, isMain); - // Main thread sweeping region is added; - if (!isMain) { - AddSweptRegionSafe(type, current); - } - current = GetRegionSafe(type); - } - - if (!isMain) { - os::memory::LockHolder holder(mutexs_[type]); - if (--remainderTaskNum_[type] == 0) { - cvs_[type].SignalAll(); - } - } -} - -void ConcurrentSweeper::SweepSpace(MemSpaceType type, Space *space, FreeListAllocator &allocator) -{ - allocator.RebuildFreeList(); - if (type == OLD_SPACE) { - auto *oldSpace = static_cast(space); - oldSpace->EnumerateNonCollectRegionSet([this, &allocator](Region *current) { FreeRegion(current, allocator); }); - } else { - space->EnumerateRegions([this, &allocator](Region *current) { FreeRegion(current, allocator); }); - } -} - -void ConcurrentSweeper::SweepHugeSpace() -{ - auto *space = const_cast(heap_->GetHugeObjectSpace()); - Region *currentRegion = space->GetRegionList().GetFirst(); - - while (currentRegion != nullptr) { - Region *next = currentRegion->GetNext(); - auto markBitmap = currentRegion->GetOrCreateMarkBitmap(); - bool isMarked = false; - markBitmap->IterateOverMarkedChunks([&isMarked]([[maybe_unused]] void *mem) { isMarked = true; }); - if (!isMarked) { - space->Free(currentRegion); - } - currentRegion = next; - } -} - -void ConcurrentSweeper::FreeRegion(Region *current, FreeListAllocator &allocator, bool isMain) -{ - auto markBitmap = current->GetOrCreateMarkBitmap(); - ASSERT(markBitmap != nullptr); - uintptr_t freeStart = current->GetBegin(); - markBitmap->IterateOverMarkedChunks([this, ¤t, &freeStart, &allocator, isMain](void *mem) { - ASSERT(current->InRange(ToUintPtr(mem))); - auto header = reinterpret_cast(mem); - auto klass = header->GetClass(); - auto size = klass->SizeFromJSHClass(header); - - uintptr_t freeEnd = ToUintPtr(mem); - if (freeStart != freeEnd) { - FreeLiveRange(allocator, current, freeStart, freeEnd, isMain); - } - freeStart = freeEnd + size; - }); - uintptr_t freeEnd = current->GetEnd(); - if (freeStart != freeEnd) { - FreeLiveRange(allocator, current, freeStart, freeEnd, isMain); - } -} - -void ConcurrentSweeper::FillSweptRegion(MemSpaceType type) -{ - if (sweptList_[type].empty()) { - return; - } - FreeListAllocator &allocator = heap_->GetHeapManager()->GetFreeListAllocator(type); - Region *region = nullptr; - while ((region = GetSweptRegionSafe(type)) != nullptr) { - region->EnumerateKinds([&allocator](FreeObjectKind *kind) { - if (kind == nullptr || kind->Empty()) { - return; - } - allocator.FillFreeList(kind); - }); - } -} - -void ConcurrentSweeper::FreeLiveRange(FreeListAllocator &allocator, Region *current, uintptr_t freeStart, - uintptr_t freeEnd, bool isMain) -{ - heap_->ClearSlotsRange(current, freeStart, freeEnd); - allocator.Free(freeStart, freeEnd, isMain); -} - -void ConcurrentSweeper::AddRegion(MemSpaceType type, Region *region) -{ - sweepingList_[type].emplace_back(region); -} - -Region *ConcurrentSweeper::GetRegionSafe(MemSpaceType type) -{ - os::memory::LockHolder holder(mutexs_[type]); - Region *region = nullptr; - if (!sweepingList_[type].empty()) { - region = sweepingList_[type].back(); - sweepingList_[type].pop_back(); - } - return region; -} - -void ConcurrentSweeper::AddSweptRegionSafe(MemSpaceType type, Region *region) -{ - os::memory::LockHolder holder(mutexs_[type]); - sweptList_[type].emplace_back(region); -} - -Region *ConcurrentSweeper::GetSweptRegionSafe(MemSpaceType type) -{ - os::memory::LockHolder holder(mutexs_[type]); - Region *region = nullptr; - if (!sweptList_[type].empty()) { - region = sweptList_[type].back(); - sweptList_[type].pop_back(); - } - return region; -} - -void ConcurrentSweeper::EnsureAllTaskFinished() -{ - if (!isSweeping_) { - return; - } - for (int i = startSpaceType_; i < FREE_LIST_NUM; i++) { - WaitingTaskFinish(static_cast(i)); - } - isSweeping_ = false; -} - -void ConcurrentSweeper::WaitingTaskFinish(MemSpaceType type) -{ - if (remainderTaskNum_[type] > 0) { - SweepSpace(type); - { - os::memory::LockHolder holder(mutexs_[type]); - while (remainderTaskNum_[type] > 0) { - cvs_[type].Wait(&mutexs_[type]); - } - } - } - FinishSweeping(type); -} - -void ConcurrentSweeper::FinishSweeping(MemSpaceType type) -{ - FillSweptRegion(type); - FreeListAllocator &allocator = heap_->GetHeapManager()->GetFreeListAllocator(type); - allocator.SetSweeping(false); - if (type == OLD_SPACE) { - heap_->RecomputeLimits(); - } -} - -bool ConcurrentSweeper::SweeperTask::Run([[maybe_unused]] uint32_t threadIndex) -{ - int sweepTypeNum = FREE_LIST_NUM - sweeper_->startSpaceType_; - for (size_t i = sweeper_->startSpaceType_; i < FREE_LIST_NUM; i++) { - auto type = static_cast(((i + type_) % sweepTypeNum) + sweeper_->startSpaceType_); - sweeper_->SweepSpace(type, false); - } - return true; -} -} // namespace panda::ecmascript diff --git a/runtime/mem/concurrent_sweeper.h b/runtime/mem/concurrent_sweeper.h deleted file mode 100644 index bbaca4486a3b0a49db46f096b0b02d4322531443..0000000000000000000000000000000000000000 --- a/runtime/mem/concurrent_sweeper.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_CONCURRENT_SWEEPER_H -#define ECMASCRIPT_MEM_CONCURRENT_SWEEPER_H - -#include -#include - -#include "plugins/ecmascript/runtime/mem/space.h" -#include "plugins/ecmascript/runtime/platform/task.h" -#include "os/mutex.h" - -namespace panda::ecmascript { -class FreeListAllocator; - -class ConcurrentSweeper { -public: - ConcurrentSweeper(Heap *heap, bool concurrentSweep); - ~ConcurrentSweeper() = default; - - NO_COPY_SEMANTIC(ConcurrentSweeper); - NO_MOVE_SEMANTIC(ConcurrentSweeper); - - void SweepPhases(bool compressGC = false); - - void EnsureAllTaskFinished(); - // Ensure task finish - void WaitingTaskFinish(MemSpaceType type); - - void FillSweptRegion(MemSpaceType type); - - bool IsConcurrentSweepEnabled() - { - return concurrentSweep_; - } - - bool CanSelectCset() const - { - return canSelectCset_; - } - -private: - class SweeperTask : public Task { - public: - SweeperTask(ConcurrentSweeper *sweeper, MemSpaceType type) : sweeper_(sweeper), type_(type) {}; - ~SweeperTask() override = default; - bool Run(uint32_t threadIndex) override; - - NO_COPY_SEMANTIC(SweeperTask); - NO_MOVE_SEMANTIC(SweeperTask); - - private: - ConcurrentSweeper *sweeper_; - MemSpaceType type_; - }; - - void SweepSpace(MemSpaceType type, bool isMain = true); - void SweepSpace(MemSpaceType type, Space *space, FreeListAllocator &allocator); - void SweepHugeSpace(); - void FinishSweeping(MemSpaceType type); - - void FreeRegion(Region *current, FreeListAllocator &allocator, bool isMain = true); - void FreeLiveRange(FreeListAllocator &allocator, Region *current, uintptr_t freeStart, uintptr_t freeEnd, - bool isMain); - - void AddRegion(MemSpaceType type, Region *region); - Region *GetRegionSafe(MemSpaceType type); - - void AddSweptRegionSafe(MemSpaceType type, Region *region); - Region *GetSweptRegionSafe(MemSpaceType type); - - std::array mutexs_; - std::array cvs_; - std::array remainderTaskNum_ = {0, 0, 0}; - - std::array, FREE_LIST_NUM> sweepingList_; - std::array, FREE_LIST_NUM> sweptList_; - - Heap *heap_; - bool concurrentSweep_ {false}; - bool isSweeping_ {false}; - bool canSelectCset_ {false}; - MemSpaceType startSpaceType_ = MemSpaceType::OLD_SPACE; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_CONCURRENT_SWEEPER_H diff --git a/runtime/mem/ecma_list.h b/runtime/mem/ecma_list.h deleted file mode 100644 index b7da121e0bebe7256e74b07c818489625f98ba9c..0000000000000000000000000000000000000000 --- a/runtime/mem/ecma_list.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_ECMALIST_H -#define ECMASCRIPT_MEM_ECMALIST_H - -#include "plugins/ecmascript/runtime/mem/mem.h" - -namespace panda::ecmascript { -// Invoking std::list will cause cross invoking, which is time-consuming. -// Therefore, we implement ecma list inside the vm. - -template -class EcmaList { -public: - EcmaList() : first_(nullptr), last_(nullptr) {} - - explicit EcmaList(T *node) : first_(node), last_(node) - { - node->LinkPrev(nullptr); - node->LinkNext(nullptr); - } - ~EcmaList() = default; - NO_COPY_SEMANTIC(EcmaList); - NO_MOVE_SEMANTIC(EcmaList); - void AddNode(T *node) - { - ASSERT(node != nullptr); - if (LIKELY(first_ != nullptr)) { - T *lastNext = last_->GetNext(); - node->LinkNext(lastNext); - node->LinkPrev(last_); - last_->LinkNext(node); - if (lastNext) { - lastNext->LinkPrev(node); - } else { - last_ = node; - } - } else { - node->LinkPrev(nullptr); - node->LinkNext(nullptr); - first_ = last_ = node; - } - length_++; - } - - void AddNodeToFirst(T *node) - { - ASSERT(node != nullptr); - if (LIKELY(last_ != nullptr)) { - node->LinkNext(first_); - node->LinkPrev(first_->GetPrev()); - first_->LinkPrev(node); - first_ = node; - } else { - node->LinkPrev(nullptr); - node->LinkNext(nullptr); - first_ = last_ = node; - } - length_++; - } - - T *PopBack() - { - T *node = last_; - RemoveNode(last_); - return node; - } - - void RemoveNode(T *node) - { - ASSERT(HasNode(node)); - if (last_ == node) { - // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) - last_ = node->GetPrev(); - } - if (first_ == node) { - // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) - first_ = node->GetNext(); - } - // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) - T *next = node->GetNext(); - // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) - T *prev = node->GetPrev(); - if (next != nullptr) { - next->LinkPrev(prev); - } - if (prev != nullptr) { - prev->LinkNext(next); - } - // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) - node->LinkPrev(nullptr); - // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) - node->LinkNext(nullptr); - length_--; - } - - bool HasNode(T *node) - { - T *it = first_; - while (it != nullptr) { - if (it == node) { - return true; - } - it = it->GetNext(); - } - return false; - } - - T *GetFirst() const - { - return first_; - } - - T *GetLast() const - { - return last_; - } - - bool IsEmpty() const - { - return last_ == nullptr; - } - - void Clear() - { - first_ = last_ = nullptr; - length_ = 0; - } - - uint32_t GetLength() const - { - return length_; - } - -private: - T *first_; - T *last_; - uint32_t length_ {0}; -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_ECMALIST_H diff --git a/runtime/mem/ecma_reference_processor.cpp b/runtime/mem/ecma_reference_processor.cpp index 5b652467b6f6a9de259dfbc84a79d4b3cab18422..bfc978f0b2f81e6158d307b9170625cd5ad8db05 100644 --- a/runtime/mem/ecma_reference_processor.cpp +++ b/runtime/mem/ecma_reference_processor.cpp @@ -21,7 +21,7 @@ #include "plugins/ecmascript/runtime/js_hclass.h" #include "plugins/ecmascript/runtime/js_weak_container.h" #include "plugins/ecmascript/runtime/linked_hash_table-inl.h" -#include "plugins/ecmascript/runtime/mem/tagged_object.h" +#include "plugins/ecmascript/runtime/js_tagged_value-inl.h" namespace panda::mem::ecmascript { diff --git a/runtime/mem/c_string.cpp b/runtime/mem/ecma_string.cpp similarity index 42% rename from runtime/mem/c_string.cpp rename to runtime/mem/ecma_string.cpp index 959db4c50e7dd2758030a67ea349dcb6dc77ba66..d41bc89e438cd694be7e99e8ed0457c0a8b3a85a 100644 --- a/runtime/mem/c_string.cpp +++ b/runtime/mem/ecma_string.cpp @@ -13,57 +13,20 @@ * limitations under the License. */ -#include "plugins/ecmascript/runtime/mem/c_string.h" +#include "plugins/ecmascript/runtime/mem/ecma_string.h" #include #include #include "plugins/ecmascript/runtime/ecma_string-inl.h" #include "plugins/ecmascript/runtime/js_symbol.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "libpandabase/macros.h" namespace panda::ecmascript { -constexpr int BASE = 10; - -int64_t CStringToLL(const CString &str) -{ - [[maybe_unused]] char *endPtr = nullptr; - int64_t result = std::strtoll(str.c_str(), &endPtr, BASE); - ASSERT(!(result == 0 && str.c_str() == endPtr) && "CString argument is not long long int"); - return result; -} - -uint64_t CStringToULL(const CString &str) -{ - [[maybe_unused]] char *endPtr = nullptr; - uint64_t result = std::strtoull(str.c_str(), &endPtr, BASE); - ASSERT(!(result == 0 && str.c_str() == endPtr) && "CString argument is not unsigned long long int"); - return result; -} - -float CStringToF(const CString &str) -{ - [[maybe_unused]] char *endPtr = nullptr; - float result = std::strtof(str.c_str(), &endPtr); - ASSERT(result != HUGE_VALF && "CString argument is not float"); - ASSERT(!(result == 0 && str.c_str() == endPtr) && "CString argument is not float"); - return result; -} - -double CStringToD(const CString &str) -{ - [[maybe_unused]] char *endPtr = nullptr; - double result = std::strtod(str.c_str(), &endPtr); - ASSERT(result != HUGE_VALF && "CString argument is not double"); - ASSERT(!(result == 0 && str.c_str() == endPtr) && "CString argument is not double"); - return result; -} - template -CString ConvertToString(T sp) +PandaString ConvertToPandaString(T sp) { - CString res; + PandaString res; res.reserve(sp.size()); // Also support ascii that great than 127, so using unsigned char here @@ -79,68 +42,32 @@ CString ConvertToString(T sp) return res; } -// NB! the following function need additional mem allocation, don't use when unnecessary! -CString ConvertToString(const std::string &str) -{ - CString res; - res.reserve(str.size()); - for (auto c : str) { - res.push_back(c); - } - return res; -} - -CString ConvertToString(const EcmaString *s, StringConvertedUsage usage) +PandaString ConvertToPandaString(const ecmascript::EcmaString *s, StringConvertedUsage usage) { if (s == nullptr) { - return CString(""); + return PandaString(""); } - return ConvertToString(s, 0, s->GetLength(), usage); + return ConvertToPandaString(s, 0, s->GetLength(), usage); } -CString ConvertToString(const EcmaString *s, uint32_t start, uint32_t length, StringConvertedUsage usage) +PandaString ConvertToPandaString(const EcmaString *s, uint32_t start, uint32_t length, StringConvertedUsage usage) { if (s == nullptr) { - return CString(""); + return PandaString(""); } if (s->IsUtf16()) { // Should convert utf-16 to utf-8, because uint16_t likely great than maxChar, will convert fail bool modify = (usage != StringConvertedUsage::PRINT); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) size_t len = base::utf_helper::Utf16ToUtf8Size(s->GetDataUtf16() + start, length, modify) - 1; - CVector buf(len); + PandaVector buf(len); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) len = base::utf_helper::ConvertRegionUtf16ToUtf8(s->GetDataUtf16() + start, buf.data(), length, len, 0, modify); Span sp(buf.data(), len); - return ConvertToString(sp); + return ConvertToPandaString(sp); } Span sp(s->GetDataUtf8(), s->GetLength()); - return ConvertToString(sp.SubSpan(start, length)); -} - -CString ConvertToString(JSTaggedValue key) -{ - ASSERT(key.IsStringOrSymbol()); - if (key.IsString()) { - return ConvertToString(EcmaString::ConstCast(key.GetTaggedObject())); - } - - ecmascript::JSTaggedValue desc = JSSymbol::Cast(key.GetTaggedObject())->GetDescription(); - if (desc.IsUndefined()) { - return CString("Symbol()"); - } - - return ConvertToString(EcmaString::ConstCast(desc.GetTaggedObject())); -} - -std::string CstringConvertToString(const CString &str) -{ - std::string res; - res.reserve(str.size()); - for (auto c : str) { - res.push_back(c); - } - return res; + return ConvertToPandaString(sp.SubSpan(start, length)); } } // namespace panda::ecmascript diff --git a/runtime/mem/c_string.h b/runtime/mem/ecma_string.h similarity index 57% rename from runtime/mem/c_string.h rename to runtime/mem/ecma_string.h index acb3284c601945e10d333b4d924241e8bb2fb73e..afe6dc475a42fb618bda93c90aaeb2444e2ac2bb 100644 --- a/runtime/mem/c_string.h +++ b/runtime/mem/ecma_string.h @@ -21,45 +21,24 @@ #include #include "plugins/ecmascript/runtime/common.h" -#include "plugins/ecmascript/runtime/mem/caddress_allocator.h" +#include "runtime/include/mem/panda_string.h" namespace panda::ecmascript { class EcmaString; -class JSTaggedValue; - -using CString = std::basic_string, CAddressAllocator>; -using CStringStream = std::basic_stringstream, CAddressAllocator>; // PRINT will skip '\0' in utf16 during conversion of utf8 enum StringConvertedUsage { PRINT, LOGICOPERATION }; -int64_t CStringToLL(const CString &str); -uint64_t CStringToULL(const CString &str); -float CStringToF(const CString &str); -double CStringToD(const CString &str); - -CString ConvertToString(const std::string &str); -std::string CstringConvertToString(const CString &str); - -// '\u0000' is skip according to holdZero -CString ConvertToString(const ecmascript::EcmaString *s, StringConvertedUsage usage = StringConvertedUsage::PRINT); -CString ConvertToString(const ecmascript::EcmaString *s, uint32_t start, uint32_t length, - StringConvertedUsage usage = StringConvertedUsage::PRINT); -CString ConvertToString(ecmascript::JSTaggedValue key); - -template -std::enable_if_t, CString> FloatToCString(T number) -{ - CStringStream strStream; - strStream << number; - return strStream.str(); -} +PandaString ConvertToPandaString(const ecmascript::EcmaString *s, + StringConvertedUsage usage = StringConvertedUsage::PRINT); +PandaString ConvertToPandaString(const ecmascript::EcmaString *s, uint32_t start, uint32_t length, + StringConvertedUsage usage = StringConvertedUsage::PRINT); template -std::enable_if_t, CString> ToCString(T number) +std::enable_if_t, PandaString> ToPandaString(T number) { if (number == 0) { - return CString("0"); + return PandaString("0"); } bool IsNeg = false; if (number < 0) { @@ -80,7 +59,7 @@ std::enable_if_t, CString> ToCString(T number) if (IsNeg) { buf[--position] = '-'; } - return CString(&buf[position]); + return PandaString(&buf[position]); } } // namespace panda::ecmascript diff --git a/runtime/mem/evacuation_allocator-inl.h b/runtime/mem/evacuation_allocator-inl.h deleted file mode 100644 index 915a7ca4abd789b3ca361afea0e7695a5c781180..0000000000000000000000000000000000000000 --- a/runtime/mem/evacuation_allocator-inl.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_EVACUATION_ALLOCATOR_INL_H -#define ECMASCRIPT_MEM_EVACUATION_ALLOCATOR_INL_H - -#include "plugins/ecmascript/runtime/mem/evacuation_allocator.h" - -#include "plugins/ecmascript/runtime/mem/heap-inl.h" - -namespace panda::ecmascript { -Region *EvacuationAllocator::ExpandOldSpace() -{ - os::memory::LockHolder lock(oldAllocatorLock_); - return heap_->ExpandCompressSpace(); -} - -void EvacuationAllocator::FreeSafe(uintptr_t begin, uintptr_t end) -{ - os::memory::LockHolder lock(oldAllocatorLock_); - oldSpaceAllocator_.Free(begin, end); -} - -void EvacuationAllocator::Free(uintptr_t begin, uintptr_t end, bool isAdd) -{ - oldSpaceAllocator_.Free(begin, end, isAdd); -} - -void EvacuationAllocator::FillFreeList(FreeObjectKind *kind) -{ - oldSpaceAllocator_.FillFreeList(kind); -} -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_EVACUATION_ALLOCATOR_INL_H diff --git a/runtime/mem/evacuation_allocator.cpp b/runtime/mem/evacuation_allocator.cpp deleted file mode 100644 index 5eaebb61573e2248435c3527624c1604e07a234b..0000000000000000000000000000000000000000 --- a/runtime/mem/evacuation_allocator.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/evacuation_allocator-inl.h" - -#include "plugins/ecmascript/runtime/js_hclass-inl.h" -#include "plugins/ecmascript/runtime/mem/mem_manager.h" -#include "plugins/ecmascript/runtime/mem/free_object_kind.h" -#include "plugins/ecmascript/runtime/mem/mark_word.h" -#include "plugins/ecmascript/runtime/mem/space.h" -#include "plugins/ecmascript/runtime/platform/platform.h" - -namespace panda::ecmascript { -void EvacuationAllocator::Initialize(TriggerGCType type) -{ - // Reset new space allocator - auto heapManager = heap_->GetHeapManager(); - heap_->GetNewSpace()->GetCurrentRegion()->SetHighWaterMark(heapManager->GetNewSpaceAllocator().GetTop()); - heap_->InitializeFromSpace(); - auto fromSpace = heap_->GetFromSpace(); - newSpaceAllocator_.Reset(fromSpace); - heap_->FlipNewSpace(); - // Reset old space allocator - if (type == TriggerGCType::OLD_GC) { - oldSpaceAllocator_.Reset(heap_); - } else if (type == TriggerGCType::COMPRESS_FULL_GC) { - heap_->InitializeCompressSpace(); - auto compressSpace = const_cast(heap_->GetCompressSpace()); - auto currentRegion = compressSpace->GetCurrentRegion(); - currentRegion->SetAliveObject(currentRegion->GetSize()); - oldSpaceAllocator_.Reset(compressSpace); - } else { - oldSpaceAllocator_.Swap(heapManager->GetOldSpaceAllocator()); - } -} - -void EvacuationAllocator::Finalize(TriggerGCType type) -{ - // Swap - auto heapManager = heap_->GetHeapManager(); - if (type == TriggerGCType::OLD_GC) { - auto oldSpace = const_cast(heap_->GetOldSpace()); - oldSpace->RemoveCSetFromList(); - oldSpace->Merge(const_cast(heap_->GetCompressSpace())); - heapManager->GetOldSpaceAllocator().Merge(&oldSpaceAllocator_); - } else { - if (type == TriggerGCType::COMPRESS_FULL_GC) { - heap_->FlipCompressSpace(); - } - heapManager->GetOldSpaceAllocator().Swap(oldSpaceAllocator_); - } - heapManager->GetNewSpaceAllocator().Swap(newSpaceAllocator_); - - // Reclaim Region - if (heap_->IsParallelGCEnabled()) { - isFreeTaskFinish_ = false; - Platform::GetCurrentPlatform()->PostTask(std::make_unique(this, type)); - } else { - ReclaimRegions(type); - } - - heap_->SetNewSpaceAgeMark(newSpaceAllocator_.GetTop()); -} - -bool EvacuationAllocator::AddRegionToOld(Region *region) -{ - if (!region->InYoungGeneration()) { - os::memory::LockHolder lock(oldAllocatorLock_); - const_cast(heap_->GetOldSpace())->RemoveRegionFromCSetAndList(region); - return heap_->AddRegionToCompressSpace(region); - } - { - os::memory::LockHolder lock(youngAllocatorLock_); - const_cast(heap_->GetFromSpace())->RemoveRegion(region); - } - os::memory::LockHolder lock(oldAllocatorLock_); - return heap_->AddRegionToCompressSpace(region); -} - -bool EvacuationAllocator::AddRegionToYoung(Region *region) -{ - ASSERT(region->InYoungGeneration()); - os::memory::LockHolder lock(youngAllocatorLock_); - const_cast(heap_->GetFromSpace())->RemoveRegion(region); - return heap_->AddRegionToToSpace(region); -} - -uintptr_t EvacuationAllocator::AllocateOld(size_t size) -{ - os::memory::LockHolder lock(oldAllocatorLock_); - uintptr_t result = oldSpaceAllocator_.Allocate(size); - if (UNLIKELY(result == 0)) { - // Compress bugfix - if (!heap_->FillOldSpaceAndTryGC(&oldSpaceAllocator_, false)) { - return 0; - } - result = oldSpaceAllocator_.Allocate(size); - } - return result; -} - -uintptr_t EvacuationAllocator::AllocateYoung(size_t size) -{ - os::memory::LockHolder lock(youngAllocatorLock_); - uintptr_t result = newSpaceAllocator_.Allocate(size); - if (UNLIKELY(result == 0)) { - if (!heap_->FillNewSpaceAndTryGC(&newSpaceAllocator_, false)) { - return 0; - } - result = newSpaceAllocator_.Allocate(size); - } - return result; -} - -void EvacuationAllocator::ReclaimRegions(TriggerGCType gcType) -{ - if (gcType == TriggerGCType::COMPRESS_FULL_GC) { - const_cast(heap_->GetCompressSpace())->ReclaimRegions(); - } else if (gcType == TriggerGCType::OLD_GC) { - const_cast(heap_->GetOldSpace())->ReclaimRegionCSet(); - } - const_cast(heap_->GetFromSpace())->ReclaimRegions(); - if (!isFreeTaskFinish_) { - os::memory::LockHolder holder(mutex_); - isFreeTaskFinish_ = true; - condition_.SignalAll(); - } -} - -void EvacuationAllocator::WaitFreeTaskFinish() -{ - if (!isFreeTaskFinish_) { - os::memory::LockHolder holder(mutex_); - while (!isFreeTaskFinish_) { - condition_.Wait(&mutex_); - } - } -} - -bool EvacuationAllocator::AsyncFreeRegionTask::Run([[maybe_unused]] uint32_t threadIndex) -{ - allocator_->ReclaimRegions(gcType_); - return true; -} -} // namespace panda::ecmascript diff --git a/runtime/mem/evacuation_allocator.h b/runtime/mem/evacuation_allocator.h deleted file mode 100644 index 309c0cd79974ed7348506c88d93dbdafd1a480ad..0000000000000000000000000000000000000000 --- a/runtime/mem/evacuation_allocator.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_EVACUATION_ALLOCATOR_H -#define ECMASCRIPT_MEM_EVACUATION_ALLOCATOR_H - -#include "plugins/ecmascript/runtime/mem/allocator.h" -#include "plugins/ecmascript/runtime/mem/free_object_list.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/mem_controller.h" -#include "plugins/ecmascript/runtime/platform/task.h" -#include "os/mutex.h" - -namespace panda::ecmascript { -class Heap; -class EvacuationAllocator { -public: - explicit EvacuationAllocator(Heap *heap) : heap_(heap) {}; - ~EvacuationAllocator() = default; - NO_COPY_SEMANTIC(EvacuationAllocator); - NO_MOVE_SEMANTIC(EvacuationAllocator); - - void Initialize(TriggerGCType type); - void Finalize(TriggerGCType type); - - inline uintptr_t GetNewSpaceTop() - { - return newSpaceAllocator_.GetTop(); - } - - bool AddRegionToOld(Region *region); - bool AddRegionToYoung(Region *region); - - inline Region *ExpandOldSpace(); - uintptr_t AllocateOld(size_t size); - uintptr_t AllocateYoung(size_t size); - - inline void FreeSafe(uintptr_t begin, uintptr_t end); - inline void Free(uintptr_t begin, uintptr_t end, bool isAdd = true); - inline void FillFreeList(FreeObjectKind *kind); - - void ReclaimRegions(TriggerGCType type); - - void WaitFreeTaskFinish(); - -private: - class AsyncFreeRegionTask : public Task { - public: - AsyncFreeRegionTask(EvacuationAllocator *allocator, TriggerGCType type) : allocator_(allocator), gcType_(type) - { - } - ~AsyncFreeRegionTask() override = default; - bool Run(uint32_t threadIndex) override; - - NO_COPY_SEMANTIC(AsyncFreeRegionTask); - NO_MOVE_SEMANTIC(AsyncFreeRegionTask); - - private: - EvacuationAllocator *allocator_; - TriggerGCType gcType_; - }; - - Heap *heap_; - bool isFreeTaskFinish_ = true; - BumpPointerAllocator newSpaceAllocator_; - FreeListAllocator oldSpaceAllocator_; - os::memory::Mutex youngAllocatorLock_; - os::memory::Mutex oldAllocatorLock_; - // Async free region task - os::memory::Mutex mutex_; - os::memory::ConditionVariable condition_; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_EVACUATION_ALLOCATOR_H diff --git a/runtime/mem/free_object_kind.cpp b/runtime/mem/free_object_kind.cpp deleted file mode 100644 index fee3869f25f8c62cc099c1c0455cc7fa4f171c18..0000000000000000000000000000000000000000 --- a/runtime/mem/free_object_kind.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/free_object_kind.h" - -#include "plugins/ecmascript/runtime/free_object.h" -#include "plugins/ecmascript/runtime/mem/free_object_list.h" - -namespace panda::ecmascript { -void FreeObjectKind::Free(uintptr_t begin, size_t size) -{ - auto freeObject = FreeObject::Cast(begin); - freeObject->SetNext(freeObject_); - freeObject_ = freeObject; - available_ += size; -} - -void FreeObjectKind::Rebuild() -{ - freeObject_ = nullptr; - available_ = 0; - isAdded_ = false; - next_ = nullptr; - prev_ = nullptr; -} - -FreeObject *FreeObjectKind::SearchSmallFreeObject(size_t size) -{ - FreeObject *curFreeObject = nullptr; - if (freeObject_ != nullptr && freeObject_->Available() >= size) { - curFreeObject = freeObject_; - freeObject_ = freeObject_->GetNext(); - curFreeObject->SetNext(nullptr); - available_ -= curFreeObject->Available(); - } - return curFreeObject; -} - -FreeObject *FreeObjectKind::SearchLargeFreeObject(size_t size) -{ - FreeObject *prevFreeObject = freeObject_; - FreeObject *curFreeObject = freeObject_; - while (curFreeObject != nullptr) { - if (curFreeObject->Available() >= size) { - if (curFreeObject == freeObject_) { - freeObject_ = curFreeObject->GetNext(); - } else { - prevFreeObject->SetNext(curFreeObject->GetNext()); - } - curFreeObject->SetNext(nullptr); - available_ -= curFreeObject->Available(); - return curFreeObject; - } - prevFreeObject = curFreeObject; - curFreeObject = curFreeObject->GetNext(); - } - return nullptr; -} -} // namespace panda::ecmascript diff --git a/runtime/mem/free_object_kind.h b/runtime/mem/free_object_kind.h deleted file mode 100644 index 046a16df1a390d484339e48cc15e16456efdebed..0000000000000000000000000000000000000000 --- a/runtime/mem/free_object_kind.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_FREE_OBJECT_KIND_H -#define ECMASCRIPT_MEM_FREE_OBJECT_KIND_H - -#include - -#include "libpandabase/macros.h" - -namespace panda::ecmascript { -using KindType = int32_t; - -class FreeObject; - -class FreeObjectKind { -public: - explicit FreeObjectKind(KindType type) : kindType_(type) - { - Rebuild(); - } - ~FreeObjectKind() = default; - - inline bool Empty() const - { - return available_ == 0; - } - - inline size_t Available() const - { - return available_; - } - - void Free(uintptr_t begin, size_t size); - - void Rebuild(); - - FreeObject *SearchSmallFreeObject(size_t size); - FreeObject *SearchLargeFreeObject(size_t size); - - NO_COPY_SEMANTIC(FreeObjectKind); - NO_MOVE_SEMANTIC(FreeObjectKind); - - static constexpr KindType INVALID_KIND_TYPE = -1; - -private: - FreeObjectKind *next_ = nullptr; - FreeObjectKind *prev_ = nullptr; - KindType kindType_ = INVALID_KIND_TYPE; - size_t available_ = 0; - bool isAdded_ = false; - FreeObject *freeObject_ = nullptr; - - friend class FreeObjectList; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_FREE_OBJECT_LIST_H diff --git a/runtime/mem/free_object_list-inl.h b/runtime/mem/free_object_list-inl.h deleted file mode 100644 index 908c41fb954e4c47fc495866718484eaf4361300..0000000000000000000000000000000000000000 --- a/runtime/mem/free_object_list-inl.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_FREE_OBJECT_LIST_INL_H -#define ECMASCRIPT_MEM_FREE_OBJECT_LIST_INL_H - -#include "plugins/ecmascript/runtime/mem/free_object_list.h" - -#include - -namespace panda::ecmascript { -KindType FreeObjectList::SelectKindType(size_t size) const -{ - if (size < SMALL_KIND_MAX_SIZE) { - if (UNLIKELY(size < MIN_SIZE)) { - return FreeObjectKind::INVALID_KIND_TYPE; - } - return (size >> INTERVAL_OFFSET) - smallKindOffsetIndex; - } - if (size < LARGE_KIND_MAX_SIZE) { - return MAX_BIT_OF_SIZET - __builtin_clzl(size) + LOG2_OFFSET; - } - if (size >= HUGE_KIND_MAX_SIZE) { - return NUMBER_OF_LAST_HUGE; - } - - return NUMBER_OF_LAST_LARGE; -} - -void FreeObjectList::SetNoneEmptyBit(KindType type) -{ - noneEmptyKindBitMap_ |= 1ULL << static_cast(type); -} - -void FreeObjectList::ClearNoneEmptyBit(KindType type) -{ - noneEmptyKindBitMap_ &= ~(1ULL << static_cast(type)); -} - -inline size_t FreeObjectList::CalcNextNoneEmptyIndex(KindType start) -{ - return __builtin_ffsll(noneEmptyKindBitMap_ >> static_cast(start)) + start - 1; -} -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_FREE_OBJECT_LIST_INL_H diff --git a/runtime/mem/free_object_list.cpp b/runtime/mem/free_object_list.cpp deleted file mode 100644 index 4a1480b479eef3bf827ca7fd864ff98aa872de86..0000000000000000000000000000000000000000 --- a/runtime/mem/free_object_list.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/free_object_list.h" - -#include "plugins/ecmascript/runtime/free_object.h" -#include "plugins/ecmascript/runtime/mem/free_object_kind.h" -#include "plugins/ecmascript/runtime/mem/free_object_list-inl.h" -#include "plugins/ecmascript/runtime/mem/mem.h" - -namespace panda::ecmascript { -FreeObjectList::FreeObjectList() - : kinds_(new FreeObjectKind *[NUMBER_OF_KINDS](), NUMBER_OF_KINDS), - lastKinds_(new FreeObjectKind *[NUMBER_OF_KINDS](), NUMBER_OF_KINDS) -{ - for (int i = 0; i < NUMBER_OF_KINDS; i++) { - kinds_[i] = nullptr; - lastKinds_[i] = nullptr; - } - noneEmptyKindBitMap_ = 0; -} - -FreeObjectList::~FreeObjectList() -{ - delete[] kinds_.data(); - delete[] lastKinds_.data(); - noneEmptyKindBitMap_ = 0; -} - -FreeObject *FreeObjectList::Allocator(size_t size) -{ - if (noneEmptyKindBitMap_ == 0) { - return nullptr; - } - size = AlignUp(size, static_cast(MemAlignment::MEM_ALIGN_OBJECT)); - // find from suitable - KindType type = SelectKindType(size); - if (type == FreeObjectKind::INVALID_KIND_TYPE) { - return nullptr; - } - - KindType lastType = type - 1; - for (type = CalcNextNoneEmptyIndex(type); type > lastType && type < NUMBER_OF_KINDS; - type = CalcNextNoneEmptyIndex(type + 1)) { - lastType = type; - FreeObjectKind *current = kinds_[type]; - while (current != nullptr) { - if (current->Available() < size) { - current = current->next_; - continue; - } - FreeObjectKind *next = nullptr; - FreeObject *object = nullptr; - if (type <= SMALL_KIND_MAX_INDEX) { - object = current->SearchSmallFreeObject(size); - } else { - next = current->next_; - object = current->SearchLargeFreeObject(size); - } - if (current->Empty()) { - RemoveKind(current); - } - if (object != nullptr) { - size_t objectSize = object->Available(); - available_ -= objectSize; - if (objectSize >= size) { - return object; - } - } - current = next; - } - } - return nullptr; -} - -void FreeObjectList::Free(uintptr_t start, size_t size, bool isAdd) -{ - if (start == 0 || size == 0) { - return; - } - size = AlignUp(size, static_cast(MemAlignment::MEM_ALIGN_OBJECT)); - KindType type = SelectKindType(size); - if (type == FreeObjectKind::INVALID_KIND_TYPE) { - return; - } - - Region *region = Region::ObjectAddressToRange(reinterpret_cast(start)); - auto kind = region->GetFreeObjectKind(type); - if (kind == nullptr) { - LOG_ECMA(FATAL) << "The kind of region is nullptr"; - return; - } - kind->Free(start, size); - - if (isAdd) { - if (kind->isAdded_) { - available_ += size; - } else { - AddKind(kind); - } - } -} - -void FreeObjectList::Rebuild() -{ - EnumerateKinds([](FreeObjectKind *kind) { kind->Rebuild(); }); - for (int i = 0; i < NUMBER_OF_KINDS; i++) { - kinds_[i] = nullptr; - lastKinds_[i] = nullptr; - } - available_ = 0; - noneEmptyKindBitMap_ = 0; -} - -size_t FreeObjectList::GetFreeObjectSize() const -{ - return available_; -} - -bool FreeObjectList::AddKind(FreeObjectKind *kind) -{ - if (kind == nullptr || kind->Empty() || kind->isAdded_) { - return false; - } - KindType type = kind->kindType_; - FreeObjectKind *top = kinds_[type]; - if (kind == top) { - return false; - } - if (top != nullptr) { - top->prev_ = kind; - } - kind->isAdded_ = true; - kind->next_ = top; - if (lastKinds_[type] == nullptr) { - lastKinds_[type] = kind; - } - kinds_[type] = kind; - SetNoneEmptyBit(type); - available_ += kind->Available(); - return true; -} - -void FreeObjectList::RemoveKind(FreeObjectKind *kind) -{ - if (kind == nullptr) { - return; - } - KindType type = kind->kindType_; - FreeObjectKind *top = kinds_[type]; - FreeObjectKind *end = lastKinds_[type]; - if (top == kind) { - kinds_[type] = top->next_; - } - if (end == kind) { - lastKinds_[type] = end->prev_; - } - if (kind->prev_ != nullptr) { - kind->prev_->next_ = kind->next_; - } - if (kind->next_ != nullptr) { - kind->next_->prev_ = kind->prev_; - } - if (kinds_[type] == nullptr) { - ClearNoneEmptyBit(type); - } - available_ -= kind->Available(); - kind->Rebuild(); -} - -void FreeObjectList::Merge(FreeObjectList *list) -{ - list->EnumerateTopAndLastKinds([this](FreeObjectKind *kind, FreeObjectKind *end) { - if (kind == nullptr || kind->Empty()) { - return; - } - KindType type = kind->kindType_; - FreeObjectKind *top = kinds_[type]; - if (top == nullptr) { - top = kind; - } else { - lastKinds_[type]->next_ = kind; - kind->prev_ = lastKinds_[type]; - } - lastKinds_[type] = end; - SetNoneEmptyBit(type); - }); - available_ += list->available_; - list->Rebuild(); -} - -template -void FreeObjectList::EnumerateKinds(const Callback &cb) const -{ - for (KindType i = 0; i < NUMBER_OF_KINDS; i++) { - EnumerateKinds(i, cb); - } -} - -template -void FreeObjectList::EnumerateKinds(KindType type, const Callback &cb) const -{ - FreeObjectKind *current = kinds_[type]; - while (current != nullptr) { - // maybe reset - FreeObjectKind *next = current->next_; - cb(current); - current = next; - } -} - -template -void FreeObjectList::EnumerateTopAndLastKinds(const Callback &cb) const -{ - for (KindType i = 0; i < NUMBER_OF_KINDS; i++) { - cb(kinds_[i], lastKinds_[i]); - } -} -} // namespace panda::ecmascript diff --git a/runtime/mem/free_object_list.h b/runtime/mem/free_object_list.h deleted file mode 100644 index 84227ef6e61cbb2223bcdbb46485b9c55d0d7c71..0000000000000000000000000000000000000000 --- a/runtime/mem/free_object_list.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_FREE_OBJECT_LIST_H -#define ECMASCRIPT_MEM_FREE_OBJECT_LIST_H - -#include - -#include "plugins/ecmascript/runtime/mem/free_object_kind.h" -#include "utils/span.h" - -namespace panda::ecmascript { -class FreeObjectList { -public: - FreeObjectList(); - ~FreeObjectList(); - - FreeObject *Allocator(size_t size); - - void Free(uintptr_t start, size_t size, bool isAdd = true); - - void Rebuild(); - - bool AddKind(FreeObjectKind *kind); - - void RemoveKind(FreeObjectKind *kind); - - void Merge(FreeObjectList *list); - - template - void EnumerateKinds(const Callback &cb) const; - - template - void EnumerateKinds(KindType type, const Callback &cb) const; - - template - void EnumerateTopAndLastKinds(const Callback &cb) const; - - NO_COPY_SEMANTIC(FreeObjectList); - NO_MOVE_SEMANTIC(FreeObjectList); - - size_t GetFreeObjectSize() const; - - static int NumberOfKinds() - { - return NUMBER_OF_KINDS; - } - -private: - static constexpr int NUMBER_OF_KINDS = 39; - static constexpr size_t MIN_SIZE = 16; - static constexpr size_t SMALL_KIND_MAX_SIZE = 256; - static constexpr size_t LARGE_KIND_MAX_SIZE = 65536; - static constexpr size_t HUGE_KIND_MAX_SIZE = 255 * 1024; - static constexpr int SMALL_KIND_MAX_INDEX = 29; - static constexpr int NUMBER_OF_LAST_LARGE = NUMBER_OF_KINDS - 2; - static constexpr int NUMBER_OF_LAST_HUGE = NUMBER_OF_KINDS - 1; - static constexpr size_t INTERVAL_OFFSET = 3; - static constexpr size_t LOG2_OFFSET = 21; - static constexpr size_t MAX_BIT_OF_SIZET = sizeof(size_t) << INTERVAL_OFFSET; - const int smallKindOffsetIndex = 2; - - inline KindType SelectKindType(size_t size) const; - - inline void SetNoneEmptyBit(KindType type); - inline void ClearNoneEmptyBit(KindType type); - inline size_t CalcNextNoneEmptyIndex(KindType start); - - size_t available_ = 0; - uint64_t noneEmptyKindBitMap_; - Span kinds_ {}; - Span lastKinds_ {}; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_FREE_OBJECT_LIST_H diff --git a/runtime/mem/gc_stats.cpp b/runtime/mem/gc_stats.cpp deleted file mode 100644 index 57e78edfc5db9f26675d6fb663e5f92eda34c1e9..0000000000000000000000000000000000000000 --- a/runtime/mem/gc_stats.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/gc_stats.h" - -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/mem.h" - -namespace panda::ecmascript { -void GCStats::PrintStatisticResult(bool isForce) -{ - LOG(ERROR, RUNTIME) << "GCStats statistic: "; - if ((isForce && semiGCCount_ != 0) || (!isForce && semiGCCount_ != lastSemiGCCount_)) { - lastSemiGCCount_ = semiGCCount_; - LOG(ERROR, RUNTIME) << " SemiCollector statistic: total semi gc count " << semiGCCount_; - LOG(ERROR, RUNTIME) << " MIN pause time: " << PrintTimeMilliseconds(semiGCMinPause_) << "ms" - << " MAX pause time: " << PrintTimeMilliseconds(semiGCMAXPause_) << "ms" - << " total pause time: " << PrintTimeMilliseconds(semiGCTotalPause_) << "ms" - << " average pause time: " << PrintTimeMilliseconds(semiGCTotalPause_ / semiGCCount_) - << "ms" - << " tatal alive size: " << sizeToMB(semiTotalAliveSize_) << "MB" - << " average alive size: " << sizeToMB(semiTotalAliveSize_ / semiGCCount_) << "MB" - << " tatal commit size: " << sizeToMB(semiTotalCommitSize_) << "MB" - << " average commit size: " << sizeToMB(semiTotalCommitSize_ / semiGCCount_) << "MB" - << " semi aliveRate: " << double(semiTotalAliveSize_) / semiTotalCommitSize_ - << " total promote size: " << sizeToMB(semiTotalPromoteSize_) << "MB" - << " average promote size: " << sizeToMB(semiTotalPromoteSize_ / semiGCCount_) << "MB"; - } - - if ((isForce && oldGCCount_ != 0) || (!isForce && lastOldGCCount_ != oldGCCount_)) { - lastOldGCCount_ = oldGCCount_; - LOG(ERROR, RUNTIME) << " MixCollector statistic: total old gc count " << oldGCCount_; - LOG(ERROR, RUNTIME) << " MIN pause time: " << PrintTimeMilliseconds(oldGCMinPause_) << "ms" - << " MAX pause time: " << PrintTimeMilliseconds(oldGCMAXPause_) << "ms" - << " total pause time: " << PrintTimeMilliseconds(oldGCTotalPause_) << "ms" - << " average pause time: " << PrintTimeMilliseconds(oldGCTotalPause_ / oldGCCount_) << "ms" - << " total free size: " << sizeToMB(oldTotalFreeSize_) << "MB" - << " average free size: " << sizeToMB(oldTotalFreeSize_ / oldGCCount_) << "MB" - << " old space total commit size: " << sizeToMB(oldSpaceTotalCommitSize_) << "MB" - << " old space average commit size: " << sizeToMB(oldSpaceTotalCommitSize_ / oldGCCount_) - << "MB" - << " non move space total commit size: " << sizeToMB(oldNonMoveTotalCommitSize_) << "MB" - << " non move space average commit size: " - << sizeToMB(oldNonMoveTotalCommitSize_ / oldGCCount_) << "MB" - << " old free rate: " - << static_cast(oldTotalFreeSize_) / - static_cast(oldSpaceTotalCommitSize_ + oldNonMoveTotalCommitSize_); - } - - if ((isForce && compressGCCount_ != 0) || (!isForce && compressGCCount_ != lastCompressGCCount_)) { - lastCompressGCCount_ = compressGCCount_; - LOG(ERROR, RUNTIME) << " compressCollector statistic: total compress gc count " << compressGCCount_; - LOG(ERROR, RUNTIME) << " MIN pause time: " << PrintTimeMilliseconds(compressGCMinPause_) << "ms" - << " MAX pause time: " << PrintTimeMilliseconds(compressGCMaxPause_) << "ms" - << " total pause time: " << PrintTimeMilliseconds(compressGCTotalPause_) << "ms" - << " average pause time: " - << PrintTimeMilliseconds(compressGCTotalPause_ / compressGCCount_) << "ms" - << " young and old total alive size: " << sizeToMB(compressYoungAndOldAliveSize_) << "MB" - << " young and old average alive size: " - << sizeToMB(compressYoungAndOldAliveSize_ / compressGCCount_) << "MB" - << " young total commit size: " << sizeToMB(compressYoungCommitSize_) << "MB" - << " old total commit size: " << sizeToMB(compressOldCommitSize_) << "MB" - << " young and old average commit size: " - << sizeToMB((compressYoungCommitSize_ + compressOldCommitSize_) / compressGCCount_) << "MB" - << " young and old free rate: " - << 1 - static_cast(compressYoungAndOldAliveSize_) / - static_cast(compressYoungCommitSize_ + compressOldCommitSize_) - << " non move total free size: " << sizeToMB(compressNonMoveTotalFreeSize_) << "MB" - << " non move total commit size: " << sizeToMB(compressNonMoveTotalCommitSize_) << "MB" - << " non move free rate: " - << static_cast(compressNonMoveTotalFreeSize_) / - static_cast(compressNonMoveTotalCommitSize_); - } - - if (isForce && heap_ != nullptr) { - auto *regionFactory = const_cast(heap_->GetRegionFactory()); - LOG(ERROR, RUNTIME) << "Memory statistic:"; - LOG(ERROR, RUNTIME) << " anno memory usage size:" << regionFactory->GetAnnoMemoryUsage() - << " anno memory max usage size:" << regionFactory->GetMaxAnnoMemoryUsage() - << " native memory usage size:" << regionFactory->GetNativeMemoryUsage() - << " native memory max usage size:" << regionFactory->GetMaxNativeMemoryUsage(); - } -} - -void GCStats::StatisticSemiCollector(Duration time, size_t aliveSize, size_t promoteSize, size_t commitSize) -{ - auto timeToMillion = TimeToMicroseconds(time); - if (semiGCCount_ == 0) { - semiGCMinPause_ = timeToMillion; - semiGCMAXPause_ = timeToMillion; - } else { - semiGCMinPause_ = std::min(semiGCMinPause_, timeToMillion); - semiGCMAXPause_ = std::max(semiGCMAXPause_, timeToMillion); - } - semiGCTotalPause_ += timeToMillion; - semiTotalAliveSize_ += aliveSize; - semiTotalCommitSize_ += commitSize; - semiTotalPromoteSize_ += promoteSize; - semiGCCount_++; -} - -void GCStats::StatisticOldCollector(Duration time, size_t freeSize, size_t oldSpaceCommitSize, - size_t nonMoveSpaceCommitSize) -{ - auto timeToMillion = TimeToMicroseconds(time); - if (oldGCCount_ == 0) { - oldGCMinPause_ = timeToMillion; - oldGCMAXPause_ = timeToMillion; - } else { - oldGCMinPause_ = std::min(oldGCMinPause_, timeToMillion); - oldGCMAXPause_ = std::max(oldGCMAXPause_, timeToMillion); - } - oldGCTotalPause_ += timeToMillion; - oldTotalFreeSize_ += freeSize; - oldSpaceTotalCommitSize_ += oldSpaceCommitSize; - oldNonMoveTotalCommitSize_ += nonMoveSpaceCommitSize; - oldGCCount_++; -} - -void GCStats::StatisticCompressCollector(Duration time, size_t youngAndOldAliveSize, size_t youngCommitSize, - size_t oldCommitSize, size_t nonMoveSpaceFreeSize, - size_t nonMoveSpaceCommitSize) -{ - auto timeToMillion = TimeToMicroseconds(time); - if (compressGCCount_ == 0) { - compressGCMinPause_ = timeToMillion; - compressGCMaxPause_ = timeToMillion; - } else { - compressGCMinPause_ = std::min(compressGCMinPause_, timeToMillion); - compressGCMaxPause_ = std::max(compressGCMaxPause_, timeToMillion); - } - compressGCTotalPause_ += timeToMillion; - compressYoungAndOldAliveSize_ += youngAndOldAliveSize; - compressYoungCommitSize_ += youngCommitSize; - compressOldCommitSize_ += oldCommitSize; - compressNonMoveTotalFreeSize_ += nonMoveSpaceFreeSize; - compressNonMoveTotalCommitSize_ += nonMoveSpaceCommitSize; - compressGCCount_++; -} -} // namespace panda::ecmascript diff --git a/runtime/mem/gc_stats.h b/runtime/mem/gc_stats.h deleted file mode 100644 index 80091309928b8e5357b30d5a09242bb42d609913..0000000000000000000000000000000000000000 --- a/runtime/mem/gc_stats.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_GC_STATS_H -#define ECMASCRIPT_MEM_GC_STATS_H - -#include -#include "chrono" -#include "libpandabase/utils/logger.h" - -namespace panda::ecmascript { -class Heap; -class GCStats { - using Duration = std::chrono::duration; - -public: - explicit GCStats(const Heap *heap) : heap_(heap) {}; - ~GCStats() = default; - - void PrintStatisticResult(bool isForce = false); - - void StatisticSemiCollector(Duration time, size_t aliveSize, size_t promoteSize, size_t commitSize); - void StatisticOldCollector(Duration time, size_t freeSize, size_t oldSpaceCommitSize, - size_t nonMoveSpaceCommitSize); - void StatisticCompressCollector(Duration time, size_t youngAndOldAliveSize, size_t youngCommitSize, - size_t oldCommitSize, size_t nonMoveSpaceFreeSize, size_t nonMoveSpaceCommitSize); - -private: - size_t TimeToMicroseconds(Duration time) - { - return std::chrono::duration_cast(time).count(); - } - - float PrintTimeMilliseconds(uint64_t time) - { - return static_cast(time) / MILLION_TIME; - } - - float sizeToMB(size_t size) - { - return static_cast(size) / MB; - } - - size_t lastSemiGCCount_ = 0; - size_t semiGCCount_ = 0; - size_t semiGCMinPause_ = 0; - size_t semiGCMAXPause_ = 0; - size_t semiGCTotalPause_ = 0; - size_t semiTotalAliveSize_ = 0; - size_t semiTotalCommitSize_ = 0; - size_t semiTotalPromoteSize_ = 0; - - size_t lastOldGCCount_ = 0; - size_t oldGCCount_ = 0; - size_t oldGCMinPause_ = 0; - size_t oldGCMAXPause_ = 0; - size_t oldGCTotalPause_ = 0; - size_t oldTotalFreeSize_ = 0; - size_t oldSpaceTotalCommitSize_ = 0; - size_t oldNonMoveTotalCommitSize_ = 0; - - size_t lastCompressGCCount_ = 0; - size_t compressGCCount_ = 0; - size_t compressGCMinPause_ = 0; - size_t compressGCMaxPause_ = 0; - size_t compressGCTotalPause_ = 0; - size_t compressYoungAndOldAliveSize_ = 0; - size_t compressYoungCommitSize_ = 0; - size_t compressOldCommitSize_ = 0; - size_t compressNonMoveTotalFreeSize_ = 0; - size_t compressNonMoveTotalCommitSize_ = 0; - - const Heap *heap_; - - static constexpr uint32_t MILLION_TIME = 1000; - static constexpr uint32_t MB = 1 * 1024 * 1024; - - NO_COPY_SEMANTIC(GCStats); - NO_MOVE_SEMANTIC(GCStats); -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_GC_STATS_H diff --git a/runtime/mem/heap-inl.h b/runtime/mem/heap-inl.h deleted file mode 100644 index 84c3d490b7aa2e1f82adbed1e49312c6e79dc3fc..0000000000000000000000000000000000000000 --- a/runtime/mem/heap-inl.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_HEAP_INL_H -#define ECMASCRIPT_MEM_HEAP_INL_H - -#include "plugins/ecmascript/runtime/mem/heap.h" - -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/mem/allocator-inl.h" -#include "plugins/ecmascript/runtime/mem/mem_controller.h" -#include "plugins/ecmascript/runtime/mem/space-inl.h" -#include "plugins/ecmascript/runtime/hprof/heap_tracker.h" -#include "plugins/ecmascript/runtime/mem/remembered_set.h" - -namespace panda::ecmascript { -template -void Heap::EnumerateOldSpaceRegions(const Callback &cb, Region *region) const -{ - oldSpace_->EnumerateRegions(cb, region); - nonMovableSpace_->EnumerateRegions(cb); - hugeObjectSpace_->EnumerateRegions(cb); - machineCodeSpace_->EnumerateRegions(cb); -} - -template -void Heap::EnumerateSnapShotSpaceRegions(const Callback &cb) const -{ - snapshotSpace_->EnumerateRegions(cb); -} - -template -void Heap::EnumerateNewSpaceRegions(const Callback &cb) const -{ - toSpace_->EnumerateRegions(cb); -} - -template -void Heap::EnumerateNonMovableRegions(const Callback &cb) const -{ - snapshotSpace_->EnumerateRegions(cb); - nonMovableSpace_->EnumerateRegions(cb); - hugeObjectSpace_->EnumerateRegions(cb); - machineCodeSpace_->EnumerateRegions(cb); -} - -template -void Heap::EnumerateRegions(const Callback &cb) const -{ - toSpace_->EnumerateRegions(cb); - oldSpace_->EnumerateRegions(cb); - snapshotSpace_->EnumerateRegions(cb); - nonMovableSpace_->EnumerateRegions(cb); - hugeObjectSpace_->EnumerateRegions(cb); - machineCodeSpace_->EnumerateRegions(cb); -} - -template -void Heap::IteratorOverObjects(const Callback &cb) const -{ - toSpace_->IterateOverObjects(cb); - oldSpace_->IterateOverObjects(cb); - nonMovableSpace_->IterateOverObjects(cb); - hugeObjectSpace_->IterateOverObjects(cb); -} - -bool Heap::FillNewSpaceAndTryGC(BumpPointerAllocator *spaceAllocator, bool allowGc) -{ - if (toSpace_->Expand(spaceAllocator->GetTop())) { - spaceAllocator->Reset(toSpace_); - TryTriggerConcurrentMarking(allowGc); - return true; - } - - if (toSpace_->GetCommittedSize() == SEMI_SPACE_SIZE_CAPACITY && - !GetEcmaVM()->GetAssociatedJSThread()->IsReadyToMark()) { - toSpace_->SetMaximumCapacity( - std::min(SEMI_SPACE_SIZE_CAPACITY + SEMI_SPACE_OVERSHOOT_SIZE, MAX_SEMI_SPACE_SIZE_STARTUP)); - if (toSpace_->Expand(spaceAllocator->GetTop())) { - spaceAllocator->Reset(toSpace_); - return true; - } - } - - if (allowGc) { - CollectGarbage(TriggerGCType::SEMI_GC); - return true; - } - return false; -} - -bool Heap::FillOldSpaceAndTryGC(FreeListAllocator *spaceAllocator, bool allowGc) -{ - if (oldSpace_->Expand()) { - if (!allowGc) { - auto currentRegion = GetCompressSpace()->GetCurrentRegion(); - currentRegion->SetAliveObject(currentRegion->GetSize()); - } - spaceAllocator->AddFree(oldSpace_->GetCurrentRegion()); - return true; - } - if (allowGc) { - CollectGarbage(TriggerGCType::OLD_GC); - return true; - } - return false; -} - -bool Heap::FillNonMovableSpaceAndTryGC(FreeListAllocator *spaceAllocator, bool allowGc) -{ - if (nonMovableSpace_->Expand()) { - spaceAllocator->AddFree(nonMovableSpace_->GetCurrentRegion()); - return true; - } - if (allowGc) { - CollectGarbage(TriggerGCType::NON_MOVE_GC); - return true; - } - return false; -} - -bool Heap::FillSnapShotSpace(BumpPointerAllocator *spaceAllocator) -{ - bool result = snapshotSpace_->Expand(spaceAllocator->GetTop()); - if (result) { - spaceAllocator->Reset(snapshotSpace_); - } - return result; -} - -bool Heap::FillMachineCodeSpaceAndTryGC(FreeListAllocator *spaceAllocator, bool allowGc) -{ - if (machineCodeSpace_->Expand()) { - spaceAllocator->AddFree(machineCodeSpace_->GetCurrentRegion()); - return true; - } - if (allowGc) { - CollectGarbage(TriggerGCType::MACHINE_CODE_GC); - return true; - } - return false; -} - -Region *Heap::ExpandCompressSpace() -{ - if (compressSpace_->Expand()) { - return compressSpace_->GetCurrentRegion(); - } - return nullptr; -} - -bool Heap::AddRegionToCompressSpace(Region *region) -{ - return compressSpace_->AddRegionToList(region); -} - -bool Heap::AddRegionToToSpace(Region *region) -{ - return toSpace_->AddRegionToList(region); -} - -void Heap::OnAllocateEvent(uintptr_t address) -{ - if (tracker_ != nullptr && address != 0) { - tracker_->AllocationEvent(address); - } -} - -void Heap::OnMoveEvent(uintptr_t address, uintptr_t forwardAddress) -{ - if (tracker_ != nullptr) { - tracker_->MoveEvent(address, forwardAddress); - } -} - -void Heap::SetNewSpaceAgeMark(uintptr_t mark) -{ - ASSERT(toSpace_ != nullptr); - toSpace_->SetAgeMark(mark); -} - -void Heap::SetNewSpaceMaximumCapacity(size_t maximumCapacity) -{ - ASSERT(toSpace_ != nullptr); - SetMaximumCapacity(toSpace_, maximumCapacity); -} - -void Heap::InitializeFromSpace() -{ - if (fromSpace_->GetCommittedSize() == 0) { - fromSpace_->Initialize(); - } -} - -void Heap::InitializeCompressSpace() -{ - if (compressSpace_->GetCommittedSize() == 0) { - compressSpace_->Initialize(); - } -} - -void Heap::SwapSpace() -{ - ASSERT(toSpace_ != nullptr); - ASSERT(fromSpace_ != nullptr); - toSpace_->Swap(fromSpace_); -} - -void Heap::ReclaimFromSpaceRegions() -{ - ASSERT(fromSpace_ != nullptr); - fromSpace_->ReclaimRegions(); -} - -void Heap::SetFromSpaceMaximumCapacity(size_t maximumCapacity) -{ - ASSERT(fromSpace_ != nullptr); - SetMaximumCapacity(fromSpace_, maximumCapacity); -} - -void Heap::ResetDelayGCMode() -{ - ASSERT(memController_ != nullptr); - memController_->ResetDelayGCMode(); -} - -void Heap::SetMaximumCapacity(SemiSpace *space, size_t maximumCapacity) -{ - space->SetMaximumCapacity(maximumCapacity); -} - -void Heap::ClearSlotsRange(Region *current, uintptr_t freeStart, uintptr_t freeEnd) -{ - auto set = current->GetOldToNewRememberedSet(); - if (set != nullptr) { - set->ClearRange(freeStart, freeEnd); - } - set = current->GetCrossRegionRememberedSet(); - if (set != nullptr) { - set->ClearRange(freeStart, freeEnd); - } -} - -size_t Heap::GetCommittedSize() const -{ - size_t result = toSpace_->GetCommittedSize() + oldSpace_->GetCommittedSize() + - hugeObjectSpace_->GetCommittedSize() + nonMovableSpace_->GetCommittedSize() + - machineCodeSpace_->GetCommittedSize(); - return result; -} - -size_t Heap::GetHeapObjectSize() const -{ - size_t result = toSpace_->GetHeapObjectSize() + oldSpace_->GetHeapObjectSize() + - hugeObjectSpace_->GetHeapObjectSize() + nonMovableSpace_->GetHeapObjectSize() + - machineCodeSpace_->GetCommittedSize(); - return result; -} -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_HEAP_INL_H diff --git a/runtime/mem/heap.cpp b/runtime/mem/heap.cpp deleted file mode 100644 index 8af3576336fa33df4d57d3e77d23d6e5f859eb91..0000000000000000000000000000000000000000 --- a/runtime/mem/heap.cpp +++ /dev/null @@ -1,604 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/heap-inl.h" - -#include - -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/mem/assert_scope-inl.h" -#include "plugins/ecmascript/runtime/mem/compress_collector.h" -#include "plugins/ecmascript/runtime/mem/concurrent_marker.h" -#include "plugins/ecmascript/runtime/mem/concurrent_sweeper.h" -#include "plugins/ecmascript/runtime/mem/mem_manager.h" -#include "plugins/ecmascript/runtime/mem/evacuation_allocator.h" -#include "plugins/ecmascript/runtime/mem/mark_stack.h" -#include "plugins/ecmascript/runtime/mem/mem_controller.h" -#include "plugins/ecmascript/runtime/mem/mix_space_collector.h" -#include "plugins/ecmascript/runtime/mem/parallel_evacuation.h" -#include "plugins/ecmascript/runtime/mem/parallel_marker-inl.h" -#include "plugins/ecmascript/runtime/mem/parallel_work_helper.h" -#include "plugins/ecmascript/runtime/mem/semi_space_collector.h" -#include "plugins/ecmascript/runtime/mem/verification.h" - -static constexpr int MAX_PARALLEL_THREAD_NUM = 3; - -namespace panda::ecmascript { -Heap::Heap(EcmaVM *ecmaVm) : ecmaVm_(ecmaVm), regionFactory_(ecmaVm->GetRegionFactory()) {} - -void Heap::Initialize() -{ - memController_ = CreateMemController(this, "no-gc-for-start-up"); - - if (memController_->IsDelayGCMode()) { - toSpace_ = new SemiSpace(this, DEFAULT_SEMI_SPACE_SIZE, MAX_SEMI_SPACE_SIZE_STARTUP); - fromSpace_ = new SemiSpace(this, DEFAULT_SEMI_SPACE_SIZE, MAX_SEMI_SPACE_SIZE_STARTUP); - } else { - toSpace_ = new SemiSpace(this); - fromSpace_ = new SemiSpace(this); - } - - toSpace_->Initialize(); - // not set up from space - oldSpace_ = new OldSpace(this); - compressSpace_ = new OldSpace(this); - oldSpace_->Initialize(); - nonMovableSpace_ = new NonMovableSpace(this); - nonMovableSpace_->Initialize(); - snapshotSpace_ = new SnapShotSpace(this); - machineCodeSpace_ = new MachineCodeSpace(this); - machineCodeSpace_->Initialize(); - hugeObjectSpace_ = new HugeObjectSpace(this); - paralledGc_ = ecmaVm_->GetJSOptions().IsEnableParallelGC(); - concurrentMarkingEnabled_ = ecmaVm_->GetJSOptions().IsEnableConcurrentMark(); -#if ECMASCRIPT_DISABLE_PARALLEL_GC - paralledGc_ = false; -#endif -#if defined(IS_STANDARD_SYSTEM) - paralledGc_ = false; - concurrentMarkingEnabled_ = false; -#endif - workList_ = new WorkerHelper(this, Platform::GetCurrentPlatform()->GetTotalThreadNum() + 1); - semiSpaceCollector_ = new SemiSpaceCollector(this, paralledGc_); - compressCollector_ = new CompressCollector(this); - - derivedPointers_ = new ChunkMap(ecmaVm_->GetChunk()); - mixSpaceCollector_ = new MixSpaceCollector(this); - sweeper_ = new ConcurrentSweeper(this, ecmaVm_->GetJSOptions().IsEnableConcurrentSweep()); - concurrentMarker_ = new ConcurrentMarker(this); - nonMovableMarker_ = new NonMovableMarker(this); - semiGcMarker_ = new SemiGcMarker(this); - compressGcMarker_ = new CompressGcMarker(this); - evacuationAllocator_ = new EvacuationAllocator(this); - evacuation_ = new ParallelEvacuation(this); -} - -void Heap::FlipNewSpace() -{ - SemiSpace *newSpace = fromSpace_; - fromSpace_ = toSpace_; - toSpace_ = newSpace; -} - -void Heap::FlipCompressSpace() -{ - OldSpace *oldSpace = compressSpace_; - compressSpace_ = oldSpace_; - oldSpace_ = oldSpace; -} - -void Heap::Destroy() -{ - Prepare(); - if (toSpace_ != nullptr) { - toSpace_->Destroy(); - delete toSpace_; - toSpace_ = nullptr; - } - if (fromSpace_ != nullptr) { - fromSpace_->Destroy(); - delete fromSpace_; - fromSpace_ = nullptr; - } - if (oldSpace_ != nullptr) { - oldSpace_->Destroy(); - delete oldSpace_; - oldSpace_ = nullptr; - } - if (compressSpace_ != nullptr) { - compressSpace_->Destroy(); - delete compressSpace_; - compressSpace_ = nullptr; - } - if (nonMovableSpace_ != nullptr) { - nonMovableSpace_->Destroy(); - delete nonMovableSpace_; - nonMovableSpace_ = nullptr; - } - if (snapshotSpace_ != nullptr) { - snapshotSpace_->Destroy(); - delete snapshotSpace_; - snapshotSpace_ = nullptr; - } - if (machineCodeSpace_ != nullptr) { - machineCodeSpace_->Destroy(); - delete machineCodeSpace_; - machineCodeSpace_ = nullptr; - } - if (hugeObjectSpace_ != nullptr) { - hugeObjectSpace_->Destroy(); - delete hugeObjectSpace_; - hugeObjectSpace_ = nullptr; - } - - delete workList_; - workList_ = nullptr; - delete semiSpaceCollector_; - semiSpaceCollector_ = nullptr; - delete mixSpaceCollector_; - mixSpaceCollector_ = nullptr; - delete compressCollector_; - compressCollector_ = nullptr; - regionFactory_ = nullptr; - delete memController_; - memController_ = nullptr; - delete sweeper_; - sweeper_ = nullptr; - delete derivedPointers_; - derivedPointers_ = nullptr; - delete concurrentMarker_; - concurrentMarker_ = nullptr; - delete nonMovableMarker_; - nonMovableMarker_ = nullptr; - delete semiGcMarker_; - semiGcMarker_ = nullptr; - delete compressGcMarker_; - compressGcMarker_ = nullptr; - delete evacuation_; - evacuation_ = nullptr; - delete evacuationAllocator_; - evacuationAllocator_ = nullptr; -} - -void Heap::Prepare() -{ - WaitRunningTaskFinished(); - sweeper_->EnsureAllTaskFinished(); - evacuationAllocator_->WaitFreeTaskFinish(); -} - -void Heap::CollectGarbage(TriggerGCType gcType) -{ - CHECK_NO_GC -#if ECMASCRIPT_ENABLE_HEAP_VERIFY - isVerifying_ = true; - // pre gc heap verify - sweeper_->EnsureAllTaskFinished(); - auto failCount = Verification(this).VerifyAll(); - if (failCount > 0) { - LOG(FATAL, GC) << "Before gc heap corrupted and " << failCount << " corruptions"; - } - isVerifying_ = false; - // verify need semiGC or fullGC. - if (gcType != TriggerGCType::SEMI_GC) { - gcType = TriggerGCType::COMPRESS_FULL_GC; - } -#endif - -#if ECMASCRIPT_SWITCH_GC_MODE_TO_COMPRESS_GC - gcType = TriggerGCType::COMPRESS_FULL_GC; -#endif - bool isDelayGCMode = memController_->IsDelayGCMode(); - if (isCompressGCRequested_ && GetEcmaVM()->GetAssociatedJSThread()->IsReadyToMark() && - gcType != TriggerGCType::COMPRESS_FULL_GC && !isDelayGCMode) { - gcType = TriggerGCType::COMPRESS_FULL_GC; - } - memController_->StartCalculationBeforeGC(); - - OPTIONAL_LOG(ecmaVm_, ERROR, ECMASCRIPT) << "Heap::CollectGarbage, gcType = " << gcType << " global CommittedSize" - << GetCommittedSize() << " global limit" << globalSpaceAllocLimit_; - switch (gcType) { - case TriggerGCType::SEMI_GC: - if (isDelayGCMode) { - SetFromSpaceMaximumCapacity(SEMI_SPACE_SIZE_CAPACITY); - SetNewSpaceMaximumCapacity(SEMI_SPACE_SIZE_CAPACITY); - compressCollector_->RunPhases(); - ResetDelayGCMode(); - } else { - bool isOldGCTriggered = false; - if (!concurrentMarkingEnabled_) { - isOldGCTriggered = - GetCommittedSize() > HALF_MAX_HEAP_SIZE ? CheckAndTriggerOldGC() : CheckAndTriggerCompressGC(); - } - if (!isOldGCTriggered) { - mixSpaceCollector_->RunPhases(); - } - } - break; - case TriggerGCType::OLD_GC: - mixSpaceCollector_->RunPhases(); - break; - case TriggerGCType::NON_MOVE_GC: - case TriggerGCType::HUGE_GC: - case TriggerGCType::MACHINE_CODE_GC: - mixSpaceCollector_->RunPhases(); - break; - case TriggerGCType::COMPRESS_FULL_GC: - compressCollector_->RunPhases(); - if (isCompressGCRequested_) { - isCompressGCRequested_ = false; - } - break; - default: - UNREACHABLE(); - break; - } - - if (gcType == TriggerGCType::COMPRESS_FULL_GC || - (gcType != TriggerGCType::SEMI_GC && !isOnlySemi_ && !sweeper_->IsConcurrentSweepEnabled())) { - // Only when the gc type is not semiGC and after the old space sweeping has been finished, - // the limits of old space and global space can be recomputed. - RecomputeLimits(); - } - memController_->StopCalculationAfterGC(gcType); - - if (toSpace_->GetMaximumCapacity() != SEMI_SPACE_SIZE_CAPACITY || - toSpace_->GetCommittedSize() > SEMI_SPACE_SIZE_CAPACITY * SEMI_SPACE_RETENTION_RATIO) { - auto capacity = AlignUp(static_cast(toSpace_->GetCommittedSize() / SEMI_SPACE_RETENTION_RATIO), - PANDA_POOL_ALIGNMENT_IN_BYTES); - capacity = std::max(capacity, SEMI_SPACE_SIZE_CAPACITY); - capacity = std::min(capacity, MAX_SEMI_SPACE_SIZE_STARTUP); - toSpace_->SetMaximumCapacity(capacity); - } - - OPTIONAL_LOG(ecmaVm_, ERROR, ECMASCRIPT) << " GC after: isOnlySemi_" << isOnlySemi_ << " global CommittedSize" - << GetCommittedSize() << " global limit" << globalSpaceAllocLimit_; - -#if ECMASCRIPT_ENABLE_GC_LOG - ecmaVm_->GetEcmaGCStats()->PrintStatisticResult(); -#endif - -#if ECMASCRIPT_ENABLE_HEAP_VERIFY - // post gc heap verify - isVerifying_ = true; - sweeper_->EnsureAllTaskFinished(); - failCount = Verification(this).VerifyAll(); - if (failCount > 0) { - LOG(FATAL, GC) << "After gc heap corrupted and " << failCount << " corruptions"; - } - isVerifying_ = false; -#endif -} - -void Heap::ThrowOutOfMemoryError(size_t size, const std::string &functionName) -{ - LOG_ECMA_MEM(FATAL) << "OOM when trying to allocate " << size << " bytes" - << " function name: " << functionName.c_str(); -} - -size_t Heap::VerifyHeapObjects() const -{ - size_t failCount = 0; - { - VerifyObjectVisitor verifier(this, &failCount); - toSpace_->IterateOverObjects(verifier); - } - - { - VerifyObjectVisitor verifier(this, &failCount); - oldSpace_->IterateOverObjects(verifier); - } - - { - VerifyObjectVisitor verifier(this, &failCount); - nonMovableSpace_->IterateOverObjects(verifier); - } - - { - VerifyObjectVisitor verifier(this, &failCount); - hugeObjectSpace_->IterateOverObjects(verifier); - } - return failCount; -} - -void Heap::RecomputeLimits() -{ - double gcSpeed = memController_->CalculateMarkCompactSpeedPerMS(); - double mutatorSpeed = memController_->GetCurrentOldSpaceAllocationThroughtputPerMS(); - size_t oldSpaceSize = oldSpace_->GetCommittedSize() + hugeObjectSpace_->GetCommittedSize(); - size_t newSpaceCapacity = toSpace_->GetCommittedSize(); - - double growingFactor = memController_->CalculateGrowingFactor(gcSpeed, mutatorSpeed); - auto newOldSpaceLimit = memController_->CalculateAllocLimit(oldSpaceSize, DEFAULT_OLD_SPACE_SIZE, - MAX_OLD_SPACE_SIZE, newSpaceCapacity, growingFactor); - auto newGlobalSpaceLimit = memController_->CalculateAllocLimit(GetCommittedSize(), DEFAULT_HEAP_SIZE, MAX_HEAP_SIZE, - newSpaceCapacity, growingFactor); - globalSpaceAllocLimit_ = newGlobalSpaceLimit; - oldSpaceAllocLimit_ = newOldSpaceLimit; -} - -bool Heap::CheckConcurrentMark(JSThread *thread) -{ - if (ConcurrentMarkingEnable() && !thread->IsReadyToMark()) { - if (thread->IsMarking()) { - [[maybe_unused]] ClockScope clockScope; - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "Heap::CheckConcurrentMark"); - WaitConcurrentMarkingFinished(); - ECMA_GC_LOG() << "wait concurrent marking finish pause time " << clockScope.TotalSpentTime(); - } - memController_->RecordAfterConcurrentMark(isOnlySemi_, concurrentMarker_); - return true; - } - return false; -} - -void Heap::TryTriggerConcurrentMarking(bool allowGc) -{ - // When the concurrent mark is enabled, concurrent mark can be tried to triggered. When the size of old space or - // global space reaches to the limits, isFullMarkNeeded will be true. If the predicted duration of the current full - // mark can allow the new space and old space to allocate to their limits, full mark will be triggered. In the same - // way, if the size of the new space reaches to the capacity, and the predicted duration of the current semi mark - // can exactly allow the new space to allocate to the capacity, semi mark can be triggered. But when it will spend - // a lot of time in full mark, the compress full GC will be requested after the spaces reach to limits. And If the - // global space is larger than the half max heap size, we will turn to use full mark and trigger mix GC. - if (!concurrentMarkingEnabled_ || !allowGc || !GetEcmaVM()->GetAssociatedJSThread()->IsReadyToMark() || - GetMemController()->IsDelayGCMode()) { - return; - } - bool isFullMarkNeeded = false; - double oldSpaceMarkDuration = 0; - double newSpaceMarkDuration = 0; - double newSpaceRemainSize = 0; - double newSpaceAllocToLimitDuration = 0; - double oldSpaceAllocToLimitDuration = 0; - double oldSpaceAllocSpeed = memController_->GetOldSpaceAllocationThroughtPerMS(); - double oldSpaceConcurrentMarkSpeed = memController_->GetFullSpaceConcurrentMarkSpeedPerMS(); - size_t oldSpaceCommittedSize = oldSpace_->GetCommittedSize() + hugeObjectSpace_->GetCommittedSize(); - size_t globalSpaceCommittedSize = GetCommittedSize(); - if (oldSpaceConcurrentMarkSpeed == 0 || oldSpaceAllocSpeed == 0) { - if (oldSpaceCommittedSize >= OLD_SPACE_LIMIT_BEGIN) { - isOnlySemi_ = false; - ECMA_GC_LOG() << "Trigger the first full mark"; - TriggerConcurrentMarking(); - } - } else { - if (oldSpaceCommittedSize >= oldSpaceAllocLimit_ || globalSpaceCommittedSize >= globalSpaceAllocLimit_) { - isFullMarkNeeded = true; - } - oldSpaceAllocToLimitDuration = - static_cast(oldSpaceAllocLimit_ - oldSpaceCommittedSize) / oldSpaceAllocSpeed; - oldSpaceMarkDuration = GetHeapObjectSize() / oldSpaceConcurrentMarkSpeed; - // oldSpaceRemainSize means the predicted size which can be allocated after the full concurrent mark. - double oldSpaceRemainSize = (oldSpaceAllocToLimitDuration - oldSpaceMarkDuration) * oldSpaceAllocSpeed; - if (oldSpaceRemainSize > 0 && oldSpaceRemainSize < DEFAULT_REGION_SIZE) { - isFullMarkNeeded = true; - } - } - - double newSpaceAllocSpeed = memController_->GetNewSpaceAllocationThroughtPerMS(); - double newSpaceConcurrentMarkSpeed = memController_->GetNewSpaceConcurrentMarkSpeedPerMS(); - - if (newSpaceConcurrentMarkSpeed == 0 || newSpaceAllocSpeed == 0) { - if (toSpace_->GetCommittedSize() >= SEMI_SPACE_TRIGGER_CONCURRENT_MARK) { - isOnlySemi_ = true; - TriggerConcurrentMarking(); - ECMA_GC_LOG() << "Trigger the first semi mark"; - } - return; - } - newSpaceAllocToLimitDuration = - static_cast(toSpace_->GetMaximumCapacity() - toSpace_->GetCommittedSize()) / newSpaceAllocSpeed; - newSpaceMarkDuration = toSpace_->GetHeapObjectSize() / newSpaceConcurrentMarkSpeed; - // newSpaceRemainSize means the predicted size which can be allocated after the semi concurrent mark. - newSpaceRemainSize = (newSpaceAllocToLimitDuration - newSpaceMarkDuration) * newSpaceAllocSpeed; - - if (isFullMarkNeeded) { - if (oldSpaceMarkDuration < newSpaceAllocToLimitDuration && - oldSpaceMarkDuration < oldSpaceAllocToLimitDuration) { - isOnlySemi_ = false; - TriggerConcurrentMarking(); - ECMA_GC_LOG() << "Trigger full mark"; - return; - } - - if (oldSpaceCommittedSize >= oldSpaceAllocLimit_ || globalSpaceCommittedSize >= globalSpaceAllocLimit_) { - if (oldSpaceCommittedSize > HALF_MAX_HEAP_SIZE) { - isOnlySemi_ = false; - TriggerConcurrentMarking(); - ECMA_GC_LOG() << "HEAP is larger than half of the max size. Trigger full mark"; - } else { - isCompressGCRequested_ = true; - ECMA_GC_LOG() << "Request compress GC"; - } - } - return; - } - - if (newSpaceRemainSize < DEFAULT_REGION_SIZE) { - isOnlySemi_ = true; - TriggerConcurrentMarking(); - ECMA_GC_LOG() << "Trigger semi mark"; - } -} - -void Heap::TriggerConcurrentMarking() -{ - if (concurrentMarkingEnabled_ && !isCompressGCRequested_) { - concurrentMarker_->ConcurrentMarking(); - } -} - -void Heap::CheckNeedFullMark() -{ - if ((oldSpace_->GetCommittedSize() + hugeObjectSpace_->GetCommittedSize()) > oldSpaceAllocLimit_) { - SetOnlyMarkSemi(false); - } -} - -bool Heap::CheckAndTriggerOldGC() -{ - if ((oldSpace_->GetCommittedSize() + hugeObjectSpace_->GetCommittedSize()) <= oldSpaceAllocLimit_) { - return false; - } - CollectGarbage(TriggerGCType::OLD_GC); - return true; -} - -bool Heap::CheckAndTriggerCompressGC() -{ - if (GetCommittedSize() <= globalSpaceAllocLimit_) { - return false; - } - CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); - return true; -} - -bool Heap::CheckAndTriggerNonMovableGC() -{ - if (nonMovableSpace_->GetCommittedSize() <= DEFAULT_NON_MOVABLE_SPACE_LIMIT) { - return false; - } - CollectGarbage(TriggerGCType::NON_MOVE_GC); - return true; -} - -bool Heap::CheckAndTriggerMachineCodeGC() -{ - if (machineCodeSpace_->GetCommittedSize() <= DEFAULT_MACHINE_CODE_SPACE_LIMIT) { - return false; - } - CollectGarbage(TriggerGCType::MACHINE_CODE_GC); - return true; -} - -void Heap::UpdateDerivedObjectInStack() -{ - if (derivedPointers_->empty()) { - return; - } - for (auto derived : *derivedPointers_) { - auto baseAddr = reinterpret_cast(derived.first.first); - JSTaggedValue base = *baseAddr; - if (base.IsHeapObject()) { - uintptr_t baseOldObject = derived.second; - auto *derivedAddr = reinterpret_cast(derived.first.second); -#ifndef NDEBUG - LOG_ECMA(DEBUG) << std::hex << "fix base before:" << baseAddr << " base old Value: " << baseOldObject - << " derived:" << derivedAddr << " old Value: " << *derivedAddr << std::endl; -#endif - // derived is always bigger than base - *derivedAddr = reinterpret_cast(base.GetHeapObject()) + (*derivedAddr - baseOldObject); -#ifndef NDEBUG - LOG_ECMA(DEBUG) << std::hex << "fix base after:" << baseAddr << " base New Value: " << base.GetHeapObject() - << " derived:" << derivedAddr << " New Value: " << *derivedAddr << std::endl; -#endif - } - } - derivedPointers_->clear(); -} - -void Heap::WaitRunningTaskFinished() -{ - os::memory::LockHolder holder(waitTaskFinishedMutex_); - while (runningTastCount_ > 0) { - waitTaskFinishedCV_.Wait(&waitTaskFinishedMutex_); - } -} - -void Heap::WaitConcurrentMarkingFinished() -{ - concurrentMarker_->WaitConcurrentMarkingFinished(); -} - -void Heap::SetConcurrentMarkingEnable(bool flag) -{ - concurrentMarkingEnabled_ = flag; -} - -bool Heap::ConcurrentMarkingEnable() const -{ - return concurrentMarkingEnabled_; -} - -void Heap::PostParallelGCTask(ParallelGCTaskPhase gcTask) -{ - IncreaseTaskCount(); - Platform::GetCurrentPlatform()->PostTask(std::make_unique(this, gcTask)); -} - -void Heap::IncreaseTaskCount() -{ - os::memory::LockHolder holder(waitTaskFinishedMutex_); - runningTastCount_++; -} - -bool Heap::CheckCanDistributeTask() -{ - os::memory::LockHolder holder(waitTaskFinishedMutex_); - return (runningTastCount_ < Platform::GetCurrentPlatform()->GetTotalThreadNum() - 1) && - (runningTastCount_ <= MAX_PARALLEL_THREAD_NUM); -} - -void Heap::ReduceTaskCount() -{ - os::memory::LockHolder holder(waitTaskFinishedMutex_); - runningTastCount_--; - if (runningTastCount_ == 0) { - waitTaskFinishedCV_.SignalAll(); - } -} - -bool Heap::ParallelGCTask::Run(uint32_t threadIndex) -{ - switch (taskPhase_) { - case ParallelGCTaskPhase::SEMI_HANDLE_THREAD_ROOTS_TASK: - heap_->GetSemiGcMarker()->MarkRoots(threadIndex); - heap_->GetSemiGcMarker()->ProcessMarkStack(threadIndex); - break; - case ParallelGCTaskPhase::SEMI_HANDLE_SNAPSHOT_TASK: - heap_->GetSemiGcMarker()->ProcessSnapshotRSet(threadIndex); - break; - case ParallelGCTaskPhase::SEMI_HANDLE_GLOBAL_POOL_TASK: - heap_->GetSemiGcMarker()->ProcessMarkStack(threadIndex); - break; - case ParallelGCTaskPhase::OLD_HANDLE_GLOBAL_POOL_TASK: - heap_->GetNonMovableMarker()->ProcessMarkStack(threadIndex); - break; - case ParallelGCTaskPhase::COMPRESS_HANDLE_GLOBAL_POOL_TASK: - heap_->GetCompressGcMarker()->ProcessMarkStack(threadIndex); - break; - case ParallelGCTaskPhase::CONCURRENT_HANDLE_GLOBAL_POOL_TASK: - heap_->GetNonMovableMarker()->ProcessMarkStack(threadIndex); - break; - case ParallelGCTaskPhase::CONCURRENT_HANDLE_OLD_TO_NEW_TASK: - heap_->GetNonMovableMarker()->ProcessOldToNew(threadIndex); - break; - default: - break; - } - heap_->ReduceTaskCount(); - return true; -} - -size_t Heap::GetArrayBufferSize() const -{ - size_t result = 0; - this->IteratorOverObjects([&result](TaggedObject *obj) { - JSHClass *jsClass = obj->GetClass(); - result += jsClass->IsArrayBuffer() ? jsClass->GetObjectSize() : 0; - }); - return result; -} -} // namespace panda::ecmascript diff --git a/runtime/mem/heap.h b/runtime/mem/heap.h deleted file mode 100644 index 2196e9ed0b7c09bd5cab23ec69aa6e92f8f611e9..0000000000000000000000000000000000000000 --- a/runtime/mem/heap.h +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_HEAP_H -#define ECMASCRIPT_MEM_HEAP_H - -#include "plugins/ecmascript/runtime/base/config.h" -#include "plugins/ecmascript/runtime/mem/chunk_containers.h" -#include "plugins/ecmascript/runtime/mem/mark_stack.h" -#include "plugins/ecmascript/runtime/mem/space.h" -#include "plugins/ecmascript/runtime/platform/platform.h" -#include "plugins/ecmascript/runtime/mem/parallel_work_helper.h" - -namespace panda::ecmascript { -class EcmaVM; -class MemManager; -class SemiSpaceCollector; -class MixSpaceCollector; -class CompressCollector; -class BumpPointerAllocator; -class FreeListAllocator; -class RegionFactory; -class HeapTracker; -class MemController; -class ConcurrentSweeper; -class ConcurrentMarker; -class Marker; -class ParallelEvacuation; -class EvacuationAllocator; -class WorkerHelper; - -using DerivedDataKey = std::pair; - -class Heap { -public: - explicit Heap(EcmaVM *ecmaVm); - ~Heap() = default; - NO_COPY_SEMANTIC(Heap); - NO_MOVE_SEMANTIC(Heap); - void Initialize(); - void Destroy(); - void Prepare(); - - const SemiSpace *GetNewSpace() const - { - return toSpace_; - } - - inline void SetNewSpaceAgeMark(uintptr_t mark); - - inline void SetNewSpaceMaximumCapacity(size_t maximumCapacity); - - const SemiSpace *GetFromSpace() const - { - return fromSpace_; - } - - const OldSpace *GetCompressSpace() const - { - return compressSpace_; - } - - inline void InitializeFromSpace(); - inline void InitializeCompressSpace(); - - inline void SwapSpace(); - - inline void ReclaimFromSpaceRegions(); - - inline void SetFromSpaceMaximumCapacity(size_t maximumCapacity); - - const OldSpace *GetOldSpace() const - { - return oldSpace_; - } - - const NonMovableSpace *GetNonMovableSpace() const - { - return nonMovableSpace_; - } - - const HugeObjectSpace *GetHugeObjectSpace() const - { - return hugeObjectSpace_; - } - - const MachineCodeSpace *GetMachineCodeSpace() const - { - return machineCodeSpace_; - } - - SemiSpaceCollector *GetSemiSpaceCollector() const - { - return semiSpaceCollector_; - } - - MixSpaceCollector *GetMixSpaceCollector() const - { - return mixSpaceCollector_; - } - - CompressCollector *GetCompressCollector() const - { - return compressCollector_; - } - - ConcurrentSweeper *GetSweeper() const - { - return sweeper_; - } - - ParallelEvacuation *GetEvacuation() const - { - return evacuation_; - } - - EvacuationAllocator *GetEvacuationAllocator() const - { - return evacuationAllocator_; - } - - ConcurrentMarker *GetConcurrentMarker() const - { - return concurrentMarker_; - } - - EcmaVM *GetEcmaVM() const - { - return ecmaVm_; - } - - WorkerHelper *GetWorkList() const - { - return workList_; - } - - void FlipNewSpace(); - - void FlipCompressSpace(); - - template - void EnumerateOldSpaceRegions(const Callback &cb, Region *region = nullptr) const; - - template - void EnumerateNewSpaceRegions(const Callback &cb) const; - - template - void EnumerateSnapShotSpaceRegions(const Callback &cb) const; - - template - void EnumerateNonMovableRegions(const Callback &cb) const; - - template - void EnumerateRegions(const Callback &cb) const; - - template - void IteratorOverObjects(const Callback &cb) const; - - void CollectGarbage(TriggerGCType gcType); - - inline bool FillNewSpaceAndTryGC(BumpPointerAllocator *spaceAllocator, bool allowGc = true); - inline bool FillOldSpaceAndTryGC(FreeListAllocator *spaceAllocator, bool allowGc = true); - inline bool FillNonMovableSpaceAndTryGC(FreeListAllocator *spaceAllocator, bool allowGc = true); - inline bool FillSnapShotSpace(BumpPointerAllocator *spaceAllocator); - inline bool FillMachineCodeSpaceAndTryGC(FreeListAllocator *spaceAllocator, bool allowGc = true); - inline Region *ExpandCompressSpace(); - inline bool AddRegionToCompressSpace(Region *region); - inline bool AddRegionToToSpace(Region *region); - - void ThrowOutOfMemoryError(size_t size, const std::string &functionName); - - void SetHeapManager(MemManager *heapManager) - { - heapManager_ = heapManager; - } - - MemManager *GetHeapManager() const - { - return heapManager_; - } - - void StartHeapTracking(HeapTracker *tracker) - { - tracker_ = tracker; - } - - void StopHeapTracking() - { - tracker_ = nullptr; - } - - inline void OnAllocateEvent(uintptr_t address); - inline void OnMoveEvent(uintptr_t address, uintptr_t forwardAddress); - - void TryTriggerConcurrentMarking(bool allowGc); - - void TriggerConcurrentMarking(); - - void CheckNeedFullMark(); - - bool CheckConcurrentMark(JSThread *thread); - - bool CheckAndTriggerOldGC(); - - bool CheckAndTriggerCompressGC(); - - bool CheckAndTriggerNonMovableGC(); - - bool CheckAndTriggerMachineCodeGC(); - - const RegionFactory *GetRegionFactory() const - { - return regionFactory_; - } - - SnapShotSpace *GetSnapShotSpace() const - { - return snapshotSpace_; - } - - bool IsLive(TaggedObject *object) const - { - if (!ContainObject(object)) { - return false; - } - - // semi space - if (toSpace_->IsLive(object)) { - return true; - } - // old space - if (oldSpace_->IsLive(object)) { - return true; - } - // non movable space - if (nonMovableSpace_->IsLive(object)) { - return true; - } - // huge object space - if (hugeObjectSpace_->IsLive(object)) { - return true; - } - return false; - } - - bool ContainObject(TaggedObject *object) const - { - // semi space - if (toSpace_->ContainObject(object)) { - return true; - } - // old space - if (oldSpace_->ContainObject(object)) { - return true; - } - // non movable space - if (nonMovableSpace_->ContainObject(object)) { - return true; - } - // huge object space - if (hugeObjectSpace_->ContainObject(object)) { - return true; - } - return false; - } - - void RecomputeLimits(); - - MemController *GetMemController() const - { - return memController_; - } - - size_t GetOldSpaceAllocLimit() - { - return oldSpaceAllocLimit_; - } - - void SetGlobalSpaceAllocLimit(size_t limit) - { - globalSpaceAllocLimit_ = limit; - } - - inline void ResetDelayGCMode(); - - size_t VerifyHeapObjects() const; - - inline void ClearSlotsRange(Region *current, uintptr_t freeStart, uintptr_t freeEnd); - - ChunkMap *GetDerivedPointers() const - { - return derivedPointers_; - } -#if ECMASCRIPT_ENABLE_HEAP_VERIFY - bool GetIsVerifying() const - { - return isVerifying_; - } -#endif - - void UpdateDerivedObjectInStack(); - static constexpr uint32_t STACK_MAP_DEFALUT_DERIVED_SIZE = 8U; - - void WaitRunningTaskFinished(); - - bool CheckCanDistributeTask(); - - void PostParallelGCTask(ParallelGCTaskPhase gcTask); - - bool IsParallelGCEnabled() const - { - return paralledGc_; - } - - void WaitConcurrentMarkingFinished(); - - void SetConcurrentMarkingEnable(bool flag); - - bool ConcurrentMarkingEnable() const; - - inline bool IsSemiMarkNeeded() const - { - return isOnlySemi_; - } - - void SetOnlyMarkSemi(bool onlySemi) - { - isOnlySemi_ = onlySemi; - } - - Marker *GetNonMovableMarker() const - { - return nonMovableMarker_; - } - - Marker *GetSemiGcMarker() const - { - return semiGcMarker_; - } - - Marker *GetCompressGcMarker() const - { - return compressGcMarker_; - } - - size_t GetArrayBufferSize() const; - - inline size_t GetCommittedSize() const; - - inline size_t GetHeapObjectSize() const; - -private: - void IncreaseTaskCount(); - - void ReduceTaskCount(); - - class ParallelGCTask : public Task { - public: - ParallelGCTask(Heap *heap, ParallelGCTaskPhase taskPhase) : heap_(heap), taskPhase_(taskPhase) {}; - ~ParallelGCTask() override = default; - bool Run(uint32_t threadIndex) override; - - NO_COPY_SEMANTIC(ParallelGCTask); - NO_MOVE_SEMANTIC(ParallelGCTask); - - private: - Heap *heap_ {nullptr}; - ParallelGCTaskPhase taskPhase_; - }; - - EcmaVM *ecmaVm_ {nullptr}; - SemiSpace *fromSpace_ {nullptr}; - SemiSpace *toSpace_ {nullptr}; - OldSpace *oldSpace_ {nullptr}; - OldSpace *compressSpace_ {nullptr}; - HugeObjectSpace *hugeObjectSpace_ {nullptr}; - SnapShotSpace *snapshotSpace_ {nullptr}; - NonMovableSpace *nonMovableSpace_ {nullptr}; - MachineCodeSpace *machineCodeSpace_ {nullptr}; - SemiSpaceCollector *semiSpaceCollector_ {nullptr}; - MixSpaceCollector *mixSpaceCollector_ {nullptr}; - CompressCollector *compressCollector_ {nullptr}; - ConcurrentSweeper *sweeper_ {nullptr}; - Marker *nonMovableMarker_ {nullptr}; - Marker *semiGcMarker_ {nullptr}; - Marker *compressGcMarker_ {nullptr}; - ParallelEvacuation *evacuation_ {nullptr}; - EvacuationAllocator *evacuationAllocator_ {nullptr}; - MemManager *heapManager_ {nullptr}; - RegionFactory *regionFactory_ {nullptr}; - HeapTracker *tracker_ {nullptr}; - MemController *memController_ {nullptr}; - size_t oldSpaceAllocLimit_ {OLD_SPACE_LIMIT_BEGIN}; - size_t globalSpaceAllocLimit_ {GLOBAL_SPACE_LIMIT_BEGIN}; - ChunkMap *derivedPointers_ {nullptr}; -#if ECMASCRIPT_ENABLE_HEAP_VERIFY - bool isVerifying_ {false}; -#endif - - ConcurrentMarker *concurrentMarker_ {nullptr}; - uint32_t runningTastCount_ {0}; - os::memory::Mutex waitTaskFinishedMutex_; - os::memory::ConditionVariable waitTaskFinishedCV_; - bool paralledGc_ {true}; - WorkerHelper *workList_ {nullptr}; - - bool concurrentMarkingEnabled_ {true}; - bool isOnlySemi_ {true}; - bool isCompressGCRequested_ {false}; - inline void SetMaximumCapacity(SemiSpace *space, size_t maximumCapacity); -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_HEAP_H diff --git a/runtime/mem/mark_stack-inl.h b/runtime/mem/mark_stack-inl.h deleted file mode 100644 index a83e6450fbad4fb2751aefcba919909abf01b664..0000000000000000000000000000000000000000 --- a/runtime/mem/mark_stack-inl.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_MARK_STACK_INL_H -#define ECMASCRIPT_MEM_MARK_STACK_INL_H - -#include "plugins/ecmascript/runtime/mem/mark_stack.h" -#include "plugins/ecmascript/runtime/mem/region_factory.h" - -namespace panda::ecmascript { -template -void ContinuousStack::BeginMarking(Heap *heap, ContinuousStack *other) -{ - heap_ = heap; - currentArea_ = other->currentArea_; - if (currentArea_ == nullptr) { - currentArea_ = RegionFactory::AllocateSpace(DEFAULT_MARK_STACK_SIZE); - } - ResetBegin(currentArea_->GetBegin(), currentArea_->GetEnd()); -} - -template -void ContinuousStack::FinishMarking(ContinuousStack *other) -{ - other->currentArea_ = currentArea_; - - while (!unusedList_.IsEmpty()) { - Area *node = unusedList_.PopBack(); - RegionFactory::FreeSpace(node); - } -} - -template -void ContinuousStack::Extend() -{ - auto area = RegionFactory::AllocateSpace(DEFAULT_MARK_STACK_SIZE); - areaList_.AddNode(currentArea_); - currentArea_ = area; - ResetBegin(currentArea_->GetBegin(), currentArea_->GetEnd()); -} - -template -void ContinuousStack::Destroy() -{ - if (currentArea_ != nullptr) { - RegionFactory::FreeSpace(currentArea_); - currentArea_ = nullptr; - } -} -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_MARK_STACK_INL_H diff --git a/runtime/mem/mark_stack.h b/runtime/mem/mark_stack.h deleted file mode 100644 index 2bbdd43fef93c6df9dc98853758f0766cf3d2f3f..0000000000000000000000000000000000000000 --- a/runtime/mem/mark_stack.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_MARK_STACK_H -#define ECMASCRIPT_MEM_MARK_STACK_H - -#include "plugins/ecmascript/runtime/mem/ecma_list.h" -#include "plugins/ecmascript/runtime/mem/space.h" -#include "plugins/ecmascript/runtime/mem/area.h" -#include "plugins/ecmascript/runtime/mem/region_factory.h" -#include "plugins/ecmascript/runtime/js_tagged_value.h" - -namespace panda::ecmascript { -class Stack { -public: - Stack() = default; - virtual ~Stack() = default; - NO_COPY_SEMANTIC(Stack); - NO_MOVE_SEMANTIC(Stack); - uintptr_t GetBegin() const - { - return begin_; - } - - uintptr_t PopBackChecked() - { - if (UNLIKELY(top_ <= reinterpret_cast(begin_))) { - return 0; - } - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - return *--top_; - } - - void PushBackUnchecked(uintptr_t obj) - { - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - *top_++ = obj; - } - - uintptr_t PopBackUnchecked() - { - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - return *--top_; - } - - bool PushBackChecked(uintptr_t obj) - { - if (UNLIKELY(top_ >= end_)) { - return false; - } - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - *top_++ = obj; - return true; - } - - bool IsEmpty() const - { - return top_ == reinterpret_cast(begin_); - } - - void ResetBegin(uintptr_t begin, uintptr_t end) - { - begin_ = begin; - top_ = reinterpret_cast(begin); - end_ = reinterpret_cast(end); - } - - void ResetTop(uintptr_t begin, uintptr_t end) - { - begin_ = begin; - top_ = end_ = reinterpret_cast(end); - } - -private: - template - friend class ContinuousStack; - friend class WorkNode; - uintptr_t begin_ {0}; - uintptr_t *end_ {nullptr}; - uintptr_t *top_ {nullptr}; -}; - -template -class ContinuousStack : public Stack { -public: - ContinuousStack() = default; - explicit ContinuousStack(Heap *heap) : heap_(heap) {} - ~ContinuousStack() override = default; - NO_COPY_SEMANTIC(ContinuousStack); - NO_MOVE_SEMANTIC(ContinuousStack); - - inline void BeginMarking(Heap *heap, ContinuousStack *other); - inline void FinishMarking(ContinuousStack *other); - - T *PopBack() - { - if (UNLIKELY(top_ <= reinterpret_cast(begin_))) { - if (!areaList_.IsEmpty()) { - unusedList_.AddNode(currentArea_); - Area *last = areaList_.PopBack(); - currentArea_ = last; - ResetTop(currentArea_->GetBegin(), currentArea_->GetEnd()); - } else { - return nullptr; - } - } - return reinterpret_cast(PopBackUnchecked()); - } - - void PushBack(T *obj) - { - if (UNLIKELY(top_ >= end_)) { - Extend(); - } - PushBackUnchecked(ToUintPtr(obj)); - } - - inline void Destroy(); - -private: - inline void Extend(); - - Heap *heap_ {nullptr}; - Area *currentArea_ {nullptr}; - EcmaList areaList_ {}; - EcmaList unusedList_ {}; -}; - -using MarkStack = ContinuousStack; -using ProcessQueue = ContinuousStack; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_MARK_STACK_H diff --git a/runtime/mem/mark_word.h b/runtime/mem/mark_word.h deleted file mode 100644 index bcbcb6e453754a14f47f6cd339350165df566009..0000000000000000000000000000000000000000 --- a/runtime/mem/mark_word.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_MARK_WORD_H -#define ECMASCRIPT_MEM_MARK_WORD_H - -#include -#include - -#include "utils/bit_field.h" -#include "libpandabase/mem/mem.h" - -namespace panda::ecmascript { -class TaggedObject; -class JSHClass; - -using MarkWordType = uint64_t; - -class MarkWord { -public: - // ForwardingAddress mark, this object has been moved and the address points to the newly allocated space. - static constexpr MarkWordType TAG_MARK_BIT = 0x02ULL; - - explicit MarkWord(TaggedObject *header) - { - value_ = reinterpret_cast *>(header)->load(std::memory_order_acquire); - } - ~MarkWord() = default; - NO_COPY_SEMANTIC(MarkWord); - NO_MOVE_SEMANTIC(MarkWord); - - bool IsForwardingAddress() - { - return (value_ & TAG_MARK_BIT) != 0; - } - - TaggedObject *ToForwardingAddress() - { - return reinterpret_cast(value_ & (~TAG_MARK_BIT)); - } - - static MarkWordType FromForwardingAddress(MarkWordType forwardAddress) - { - return forwardAddress | TAG_MARK_BIT; - } - - MarkWordType GetValue() const - { - return value_; - } - - JSHClass *GetJSHClass() const - { - return reinterpret_cast(value_ & (~TAG_MARK_BIT)); - } - -private: - MarkWordType value_ {0}; -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_MARK_WORD_H diff --git a/runtime/mem/mem.h b/runtime/mem/mem.h index d403a77f8902053ec017c6f85647153db63d2f7f..9f15c872ecf4c7a2ccf64e8c86f2f255e105fea0 100644 --- a/runtime/mem/mem.h +++ b/runtime/mem/mem.h @@ -32,70 +32,6 @@ enum class MemAlignment : uint8_t { MEM_ALIGN_REGION = 16, }; -static constexpr size_t DEFAULT_SEMI_SPACE_SIZE = 1024 * 1024; -static constexpr size_t MIN_AllOC_LIMIT_GROWING_STEP = 2 * 1024 * 1024; - -#if defined(IS_STANDARD_SYSTEM) -static constexpr size_t SEMI_SPACE_SIZE_CAPACITY = 3 * 1024 * 1024; -static constexpr size_t MAX_SEMI_SPACE_SIZE_STARTUP = 3 * 1024 * 1024; -static constexpr size_t SEMI_SPACE_TRIGGER_CONCURRENT_MARK = 2.5 * 1024 * 1024; -static constexpr size_t SEMI_SPACE_OVERSHOOT_SIZE = 2 * 1024 * 1024; -#else -static constexpr size_t SEMI_SPACE_SIZE_CAPACITY = 4 * 1024 * 1024; -static constexpr size_t MAX_SEMI_SPACE_SIZE_STARTUP = 16 * 1024 * 1024; -static constexpr size_t SEMI_SPACE_TRIGGER_CONCURRENT_MARK = 3.5 * 1024 * 1024; -static constexpr size_t SEMI_SPACE_OVERSHOOT_SIZE = 2 * 1024 * 1024; -#endif - -static constexpr size_t OLD_SPACE_LIMIT_BEGIN = 10 * 1024 * 1024; -static constexpr size_t GLOBAL_SPACE_LIMIT_BEGIN = 20 * 1024 * 1024; - -static constexpr size_t DEFAULT_OLD_SPACE_SIZE = 2 * 1024 * 1024; -static constexpr size_t MAX_OLD_SPACE_SIZE = 256 * 1024 * 1024; - -static constexpr size_t DEFAULT_NON_MOVABLE_SPACE_SIZE = 2 * 1024 * 1024; -static constexpr size_t MAX_NON_MOVABLE_SPACE_SIZE = 256 * 1024 * 1024; -static constexpr size_t DEFAULT_NON_MOVABLE_SPACE_LIMIT = 4 * 1024 * 1024; - -static constexpr size_t REGION_SIZE_LOG2 = 18U; -static constexpr size_t DEFAULT_SNAPSHOT_SPACE_SIZE = 1U << REGION_SIZE_LOG2; -static constexpr size_t MAX_SNAPSHOT_SPACE_SIZE = 8 * 1024 * 1024; - -static constexpr size_t DEFAULT_MACHINE_CODE_SPACE_SIZE = 256 * 1024; -static constexpr size_t DEFAULT_MACHINE_CODE_SPACE_LIMIT = 1024 * 1024; -static constexpr size_t MAX_MACHINE_CODE_SPACE_SIZE = 8 * 1024 * 1024; - -static constexpr size_t MAX_HEAP_SIZE = 256 * 1024 * 1024; -static constexpr size_t HALF_MAX_HEAP_SIZE = MAX_HEAP_SIZE / 2; -static constexpr size_t DEFAULT_HEAP_SIZE = 5 * 1024 * 1024; - -static constexpr size_t DEFAULT_REGION_SIZE = 1U << REGION_SIZE_LOG2; -static constexpr size_t DEFAULT_REGION_MASK = DEFAULT_REGION_SIZE - 1; - -static constexpr size_t DEFAULT_MARK_STACK_SIZE = 4 * 1024; - -// Objects which are larger than half of the region size are huge objects. -// Regular objects will be allocated on regular regions and migrated on spaces. -// They will never be moved to huge object space. So we take half of a regular -// region as the border of regular objects. -static constexpr size_t MAX_32BIT_OBJECT_SPACE_SIZE = 1 * 1024 * 1024 * 1024; -static constexpr size_t MAX_REGULAR_HEAP_OBJECT_SIZE = DEFAULT_REGION_SIZE * 2 / 3; -static constexpr size_t MAX_HUGE_OBJECT_SIZE = 256 * 1024 * 1024; -static constexpr size_t MAX_HUGE_OBJECT_SPACE_SIZE = 256 * 1024 * 1024; -static constexpr size_t LARGE_BITMAP_MIN_SIZE = static_cast(MemAlignment::MEM_ALIGN_OBJECT) - << mem::Bitmap::LOG_BITSPERWORD; - -static constexpr size_t SMALL_OBJECT_SIZE = 8 * 1024; - -// internal allocator -static constexpr size_t CHUNK_ALIGN_SIZE = 4 * 1024; -static constexpr size_t MIN_CHUNK_AREA_SIZE = 4 * 1024; -static constexpr size_t MAX_CACHED_CHUNK_AREA_SIZE = 16 * 1024; -static constexpr size_t MAX_CHUNK_AREA_SIZE = 1 * 1024 * 1024; - -static constexpr uintptr_t PANDA_32BITS_HEAP_START_ADDRESS_256 = 256_KB; -static constexpr double SEMI_SPACE_RETENTION_RATIO = 0.75; - template constexpr inline bool IsAligned(T value, size_t alignment) { diff --git a/runtime/mem/mem_controller.cpp b/runtime/mem/mem_controller.cpp deleted file mode 100644 index 8dcdae6cf1ef8027956aa405145a8822988828fb..0000000000000000000000000000000000000000 --- a/runtime/mem/mem_controller.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/mem_controller.h" - -#include "plugins/ecmascript/runtime/mem/concurrent_marker.h" -#include "plugins/ecmascript/runtime/mem/mem_manager.h" -#include "plugins/ecmascript/runtime/mem/heap-inl.h" -#include "plugins/ecmascript/runtime/mem/parallel_evacuation.h" - -namespace panda::ecmascript { -MemController::MemController(Heap *heap, bool isDelayGCMode) : heap_(heap), isDelayGCMode_(isDelayGCMode) {} - -double MemController::CalculateAllocLimit(size_t currentSize, size_t minSize, size_t maxSize, - [[maybe_unused]] size_t newSpaceCapacity, double factor) const -{ - const uint64_t limit = std::max(static_cast(currentSize * factor), - static_cast(currentSize) + MIN_AllOC_LIMIT_GROWING_STEP) + - newSpaceCapacity; - - const uint64_t limitAboveMinSize = std::max(limit, minSize); - const uint64_t halfToMaxSize = (static_cast(currentSize) + maxSize) / 2; - const auto result = static_cast(std::min(limitAboveMinSize, halfToMaxSize)); - return result; -} - -double MemController::CalculateGrowingFactor(double gcSpeed, double mutatorSpeed) -{ - static constexpr double minGrowingFactor = 1.3; - static constexpr double maxGrowingFactor = 2.0; - static constexpr double targetMutatorUtilization = 0.97; - if (gcSpeed == 0 || mutatorSpeed == 0) { - return maxGrowingFactor; - } - - const double speedRatio = gcSpeed / mutatorSpeed; - - const double a = speedRatio * (1 - targetMutatorUtilization); - const double b = speedRatio * (1 - targetMutatorUtilization) - targetMutatorUtilization; - - double factor = (a < b * maxGrowingFactor) ? a / b : maxGrowingFactor; - factor = std::min(maxGrowingFactor, factor); - factor = std::max(factor, minGrowingFactor); - return factor; -} - -void MemController::StartCalculationBeforeGC() -{ - startCounter_++; - if (startCounter_ != 1) { - return; - } - - auto heapManager = heap_->GetHeapManager(); - // It's unnecessary to calculate newSpaceAllocAccumulatorSize. newSpaceAllocBytesSinceGC can be calculated directly. - size_t newSpaceAllocBytesSinceGC = heap_->GetNewSpace()->GetAllocatedSizeSinceGC(); - size_t hugeObjectAllocSizeSinceGC = heap_->GetHugeObjectSpace()->GetHeapObjectSize() - hugeObjectAllocSizeSinceGC_; - size_t oldSpaceAllocAccumulatorSize = - heapManager->GetOldSpaceAllocator().GetAllocatedSize() + heap_->GetEvacuation()->GetPromotedAccumulatorSize(); - size_t nonMovableSpaceAllocAccumulatorSize = heapManager->GetNonMovableSpaceAllocator().GetAllocatedSize(); - size_t codeSpaceAllocAccumulatorSize = heapManager->GetMachineCodeSpaceAllocator().GetAllocatedSize(); - if (allocTimeMs_ == 0) { - allocTimeMs_ = GetSystemTimeInMs(); - oldSpaceAllocAccumulatorSize_ = oldSpaceAllocAccumulatorSize; - nonMovableSpaceAllocAccumulatorSize_ = nonMovableSpaceAllocAccumulatorSize; - codeSpaceAllocAccumulatorSize_ = codeSpaceAllocAccumulatorSize; - return; - } - double currentTimeInMs = GetSystemTimeInMs(); - gcStartTime_ = currentTimeInMs; - size_t oldSpaceAllocSize = oldSpaceAllocAccumulatorSize - oldSpaceAllocAccumulatorSize_; - size_t nonMovableSpaceAllocSize = nonMovableSpaceAllocAccumulatorSize - nonMovableSpaceAllocAccumulatorSize_; - size_t codeSpaceAllocSize = codeSpaceAllocAccumulatorSize - codeSpaceAllocAccumulatorSize_; - - double duration = currentTimeInMs - allocTimeMs_; - allocTimeMs_ = currentTimeInMs; - oldSpaceAllocAccumulatorSize_ = oldSpaceAllocAccumulatorSize; - nonMovableSpaceAllocAccumulatorSize_ = nonMovableSpaceAllocAccumulatorSize; - codeSpaceAllocAccumulatorSize_ = codeSpaceAllocAccumulatorSize; - allocDurationSinceGc_ += duration; - newSpaceAllocSizeSinceGC_ += newSpaceAllocBytesSinceGC; - oldSpaceAllocSizeSinceGC_ += oldSpaceAllocSize; - oldSpaceAllocSizeSinceGC_ += hugeObjectAllocSizeSinceGC; - nonMovableSpaceAllocSizeSinceGC_ += nonMovableSpaceAllocSize; - codeSpaceAllocSizeSinceGC_ += codeSpaceAllocSize; -} - -void MemController::StopCalculationAfterGC(TriggerGCType gcType) -{ - startCounter_--; - if (startCounter_ != 0) { - return; - } - - gcEndTime_ = GetSystemTimeInMs(); - allocTimeMs_ = gcEndTime_; - if (allocDurationSinceGc_ > 0) { - recordedNewSpaceAllocations_.Push(MakeBytesAndDuration(newSpaceAllocSizeSinceGC_, allocDurationSinceGc_)); - recordedOldSpaceAllocations_.Push(MakeBytesAndDuration(oldSpaceAllocSizeSinceGC_, allocDurationSinceGc_)); - recordedNonmovableSpaceAllocations_.Push( - MakeBytesAndDuration(nonMovableSpaceAllocSizeSinceGC_, allocDurationSinceGc_)); - recordedCodeSpaceAllocations_.Push(MakeBytesAndDuration(codeSpaceAllocSizeSinceGC_, allocDurationSinceGc_)); - } - allocDurationSinceGc_ = 0.0; - newSpaceAllocSizeSinceGC_ = 0; - oldSpaceAllocSizeSinceGC_ = 0; - nonMovableSpaceAllocSizeSinceGC_ = 0; - codeSpaceAllocSizeSinceGC_ = 0; - - hugeObjectAllocSizeSinceGC_ = heap_->GetHugeObjectSpace()->GetHeapObjectSize(); - - double duration = gcEndTime_ - gcStartTime_; - - switch (gcType) { - case TriggerGCType::SEMI_GC: - case TriggerGCType::NON_MOVE_GC: - case TriggerGCType::HUGE_GC: - case TriggerGCType::MACHINE_CODE_GC: - break; - case TriggerGCType::OLD_GC: - case TriggerGCType::COMPRESS_FULL_GC: { - size_t heapObjectSize = heap_->GetHeapObjectSize(); - recordedMarkCompacts_.Push(MakeBytesAndDuration(heapObjectSize, duration)); - break; - } - default: - UNREACHABLE(); - break; - } -} - -void MemController::RecordAfterConcurrentMark(const bool isSemi, const ConcurrentMarker *marker) -{ - double duration = marker->GetDuration(); - if (isSemi) { - recordedSemiConcurrentMarks_.Push(MakeBytesAndDuration(marker->GetHeapObjectSize(), duration)); - } else { - recordedConcurrentMarks_.Push(MakeBytesAndDuration(marker->GetHeapObjectSize(), duration)); - } -} - -double MemController::CalculateMarkCompactSpeedPerMS() -{ - if (markCompactSpeedCache_ > 0) { - return markCompactSpeedCache_; - } - markCompactSpeedCache_ = CalculateAverageSpeed(recordedMarkCompacts_); - if (markCompactSpeedCache_ > 0) { - return markCompactSpeedCache_; - } - return 0; -} - -double MemController::CalculateAverageSpeed(const base::GCRingBuffer &buffer, - const BytesAndDuration &initial, double timeMs) -{ - BytesAndDuration sum = buffer.Sum( - [timeMs](BytesAndDuration a, BytesAndDuration b) { - if (timeMs != 0 && a.second >= timeMs) { - return a; - } - return std::make_pair(a.first + b.first, a.second + b.second); - }, - initial); - uint64_t bytes = sum.first; - double durations = sum.second; - if (durations == 0.0) { - return 0; - } - double speed = bytes / durations; - const int maxSpeed = 1024 * 1024 * 1024; - const int minSpeed = 1; - if (speed >= maxSpeed) { - return maxSpeed; - } - if (speed <= minSpeed) { - return minSpeed; - } - return speed; -} - -double MemController::CalculateAverageSpeed(const base::GCRingBuffer &buffer) -{ - return CalculateAverageSpeed(buffer, MakeBytesAndDuration(0, 0), 0); -} - -double MemController::GetCurrentOldSpaceAllocationThroughtputPerMS(double timeMs) const -{ - size_t allocatedSize = oldSpaceAllocSizeSinceGC_; - double duration = allocDurationSinceGc_; - return CalculateAverageSpeed(recordedOldSpaceAllocations_, MakeBytesAndDuration(allocatedSize, duration), timeMs); -} - -double MemController::GetNewSpaceAllocationThroughtPerMS() const -{ - return CalculateAverageSpeed(recordedNewSpaceAllocations_); -} - -double MemController::GetNewSpaceConcurrentMarkSpeedPerMS() const -{ - return CalculateAverageSpeed(recordedSemiConcurrentMarks_); -} - -double MemController::GetOldSpaceAllocationThroughtPerMS() const -{ - return CalculateAverageSpeed(recordedOldSpaceAllocations_); -} - -double MemController::GetFullSpaceConcurrentMarkSpeedPerMS() const -{ - return CalculateAverageSpeed(recordedConcurrentMarks_); -} - -MemController *CreateMemController(Heap *heap, std::string_view gcTriggerType) -{ - MemController *ret {nullptr}; - if (gcTriggerType == "no-gc-for-start-up") { - ret = new MemController(heap, true); - } else if (gcTriggerType == "heap-trigger") { - ret = new MemController(heap, false); - } - return ret; -} -} // namespace panda::ecmascript diff --git a/runtime/mem/mem_controller.h b/runtime/mem/mem_controller.h deleted file mode 100644 index 5260270804033c62210690507746c91a9840fafe..0000000000000000000000000000000000000000 --- a/runtime/mem/mem_controller.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_MEM_CONTROLLER_H -#define ECMASCRIPT_MEM_MEM_CONTROLLER_H - -#include - -#include "plugins/ecmascript/runtime/base/gc_ring_buffer.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/mem.h" - -namespace panda::ecmascript { -constexpr static int MILLISECONDS_PER_SECOND = 1000; - -using BytesAndDuration = std::pair; - -inline BytesAndDuration MakeBytesAndDuration(uint64_t bytes, double duration) -{ - return std::make_pair(bytes, duration); -} - -class MemController { -public: - explicit MemController(Heap *heap, bool isDelayGCMode = false); - MemController() = default; - ~MemController() = default; - NO_COPY_SEMANTIC(MemController); - NO_MOVE_SEMANTIC(MemController); - - static double GetSystemTimeInMs() - { - double currentTime = - std::chrono::duration(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); - return currentTime * MILLISECOND_PER_SECOND; - } - - double CalculateAllocLimit(size_t currentSize, size_t minSize, size_t maxSize, size_t newSpaceCapacity, - double factor) const; - - double CalculateGrowingFactor(double gcSpeed, double mutatorSpeed); - - inline bool IsDelayGCMode() const - { - return isDelayGCMode_; - } - - void ResetDelayGCMode() - { - isDelayGCMode_ = false; - } - - void StartCalculationBeforeGC(); - void StopCalculationAfterGC(TriggerGCType gcType); - - void RecordAfterConcurrentMark(bool isSemi, const ConcurrentMarker *marker); - - double CalculateMarkCompactSpeedPerMS(); - double GetCurrentOldSpaceAllocationThroughtputPerMS(double timeMs = THROUGHPUT_TIME_FRAME_MS) const; - double GetNewSpaceAllocationThroughtPerMS() const; - double GetOldSpaceAllocationThroughtPerMS() const; - double GetNewSpaceConcurrentMarkSpeedPerMS() const; - double GetFullSpaceConcurrentMarkSpeedPerMS() const; - - double GetAllocTimeMs() const - { - return allocTimeMs_; - } - - size_t GetOldSpaceAllocAccumulatorSize() const - { - return oldSpaceAllocAccumulatorSize_; - } - - size_t GetNonMovableSpaceAllocAccumulatorSize() const - { - return nonMovableSpaceAllocAccumulatorSize_; - } - - size_t GetCodeSpaceAllocAccumulatorSize() const - { - return codeSpaceAllocAccumulatorSize_; - } - - double GetAllocDurationSinceGc() const - { - return allocDurationSinceGc_; - } - - size_t GetNewSpaceAllocSizeSinceGC() const - { - return newSpaceAllocSizeSinceGC_; - } - - size_t GetOldSpaceAllocSizeSinceGC() const - { - return oldSpaceAllocSizeSinceGC_; - } - - size_t GetNonMovableSpaceAllocSizeSinceGC() const - { - return nonMovableSpaceAllocSizeSinceGC_; - } - - size_t GetCodeSpaceAllocSizeSinceGC() const - { - return codeSpaceAllocSizeSinceGC_; - } - - size_t GetHugeObjectAllocSizeSinceGC() const - { - return hugeObjectAllocSizeSinceGC_; - } - -private: - static constexpr int LENGTH = 10; - static double CalculateAverageSpeed(const base::GCRingBuffer &buffer); - static double CalculateAverageSpeed(const base::GCRingBuffer &buffer, - const BytesAndDuration &initial, double timeMs); - - Heap *heap_ {nullptr}; - - double gcStartTime_ {0.0}; - double gcEndTime_ {0.0}; - - // Time and allocation accumulators. - double allocTimeMs_ {0.0}; - size_t oldSpaceAllocAccumulatorSize_ {0}; - size_t nonMovableSpaceAllocAccumulatorSize_ {0}; - size_t codeSpaceAllocAccumulatorSize_ {0}; - - // Duration and allocation size in last gc. - double allocDurationSinceGc_ {0.0}; - size_t newSpaceAllocSizeSinceGC_ {0}; - size_t oldSpaceAllocSizeSinceGC_ {0}; - size_t nonMovableSpaceAllocSizeSinceGC_ {0}; - size_t codeSpaceAllocSizeSinceGC_ {0}; - size_t hugeObjectAllocSizeSinceGC_ {0}; - - int startCounter_ {0}; - double markCompactSpeedCache_ {0.0}; - - base::GCRingBuffer recordedMarkCompacts_; - base::GCRingBuffer recordedNewSpaceAllocations_; - base::GCRingBuffer recordedOldSpaceAllocations_; - base::GCRingBuffer recordedNonmovableSpaceAllocations_; - base::GCRingBuffer recordedCodeSpaceAllocations_; - - base::GCRingBuffer recordedConcurrentMarks_; - base::GCRingBuffer recordedSemiConcurrentMarks_; - bool isDelayGCMode_ {false}; - - static constexpr double THROUGHPUT_TIME_FRAME_MS = 5000; - static constexpr int MILLISECOND_PER_SECOND = 1000; -}; - -MemController *CreateMemController(Heap *heap, std::string_view gcTriggerType); -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_MEM_CONTROLLER_H diff --git a/runtime/mem/mem_manager-inl.h b/runtime/mem/mem_manager-inl.h index 90912ec9838a80bc30f072c3c1a2fe9e444b2b04..bb070a4c4a9dde14debb704b81ad163be66f3894 100644 --- a/runtime/mem/mem_manager-inl.h +++ b/runtime/mem/mem_manager-inl.h @@ -20,8 +20,6 @@ #include -#include "plugins/ecmascript/runtime/mem/allocator-inl.h" -#include "plugins/ecmascript/runtime/mem/heap-inl.h" #include "plugins/ecmascript/runtime/mem/object_xray.h" #include "plugins/ecmascript/runtime/js_hclass.h" @@ -35,12 +33,6 @@ TaggedObject *MemManager::AllocateYoungGenerationOrHugeObject(JSHClass *hclass) TaggedObject *MemManager::AllocateYoungGenerationOrHugeObject(JSHClass *hclass, size_t size) { auto object = heapManager_->AllocateObject(hclass->GetHClass(), size, DEFAULT_ALIGNMENT, thread_); - // OnAllocateEvent checks object for nullptr - // SUPPRESS_CSA_NEXTLINE(alpha.core.CheckObjHeaderTypeRef) - heap_->OnAllocateEvent(reinterpret_cast(object)); - // CSA detects that OnAllocateEven potentionally may trigger GC but in the real situation cannot. - // OnAllocateEven leads to HeapSnapShot class which may allocate an object in JSObject::GetProperty. - // Snapshots doesn't work now so this situation is impossible. // SUPPRESS_CSA_NEXTLINE(alpha.core.WasteObjHeader) return TaggedObject::Cast(object); } @@ -58,33 +50,10 @@ TaggedObject *MemManager::AllocateNonMovableOrHugeObject(JSHClass *hclass, size_ } else { object = heapManager_->AllocateNonMovableObject(hclass->GetHClass(), size, DEFAULT_ALIGNMENT, thread_); } - // OnAllocateEvent checks object for nullptr - // SUPPRESS_CSA_NEXTLINE(alpha.core.CheckObjHeaderTypeRef) - heap_->OnAllocateEvent(reinterpret_cast(object)); - // CSA detects that OnAllocateEven potentionally may trigger GC but in the real situation cannot. - // OnAllocateEven leads to HeapSnapShot class which may allocate an object in JSObject::GetProperty. - // Snapshots doesn't work now so this situation is impossible. // SUPPRESS_CSA_NEXTLINE(alpha.core.WasteObjHeader) return TaggedObject::Cast(object); } -uintptr_t MemManager::AllocateSnapShotSpace(size_t size) -{ - uintptr_t object = snapshotSpaceAllocator_.Allocate(size); - if (UNLIKELY(object == 0)) { - if (!heap_->FillSnapShotSpace(&snapshotSpaceAllocator_)) { - LOG_ECMA_MEM(FATAL) << "alloc failed"; - UNREACHABLE(); - } - object = snapshotSpaceAllocator_.Allocate(size); - if (UNLIKELY(object == 0)) { - LOG_ECMA_MEM(FATAL) << "alloc failed"; - UNREACHABLE(); - } - } - return object; -} - void MemManager::SetClass(TaggedObject *header, JSHClass *hclass) { header->SetClass(hclass); @@ -99,12 +68,6 @@ TaggedObject *MemManager::AllocateNonMovableOrHugeObject(JSHClass *hclass) TaggedObject *MemManager::AllocateOldGenerationOrHugeObject(JSHClass *hclass, size_t size) { auto object = heapManager_->AllocateObject(hclass->GetHClass(), size, DEFAULT_ALIGNMENT, thread_); - // OnAllocateEvent checks object for nullptr - // SUPPRESS_CSA_NEXTLINE(alpha.core.CheckObjHeaderTypeRef) - heap_->OnAllocateEvent(reinterpret_cast(object)); - // CSA detects that OnAllocateEven potentionally may trigger GC but in the real situation cannot. - // OnAllocateEven leads to HeapSnapShot class which may allocate an object in JSObject::GetProperty. - // Snapshots doesn't work now so this situation is impossible. // SUPPRESS_CSA_NEXTLINE(alpha.core.WasteObjHeader) return TaggedObject::Cast(object); } @@ -112,46 +75,9 @@ TaggedObject *MemManager::AllocateOldGenerationOrHugeObject(JSHClass *hclass, si TaggedObject *MemManager::AllocateHugeObject(JSHClass *hclass, size_t size) { auto object = heapManager_->AllocateObject(hclass->GetHClass(), size, DEFAULT_ALIGNMENT, thread_); - // OnAllocateEvent checks object for nullptr - // SUPPRESS_CSA_NEXTLINE(alpha.core.CheckObjHeaderTypeRef) - heap_->OnAllocateEvent(reinterpret_cast(object)); - // CSA detects that OnAllocateEven potentionally may trigger GC but in the real situation cannot. - // OnAllocateEven leads to HeapSnapShot class which may allocate an object in JSObject::GetProperty. - // Snapshots doesn't work now so this situation is impossible. // SUPPRESS_CSA_NEXTLINE(alpha.core.WasteObjHeader) return TaggedObject::Cast(object); } - -TaggedObject *MemManager::AllocateMachineCodeSpaceObject(JSHClass *hclass, size_t size) -{ - auto object = reinterpret_cast(GetMachineCodeSpaceAllocator().Allocate(size)); - if (UNLIKELY(object == nullptr)) { - if (heap_->CheckAndTriggerMachineCodeGC()) { - object = reinterpret_cast(GetMachineCodeSpaceAllocator().Allocate(size)); - } - if (UNLIKELY(object == nullptr)) { - if (!heap_->FillMachineCodeSpaceAndTryGC(&GetMachineCodeSpaceAllocator())) { - return nullptr; - } - object = reinterpret_cast(GetMachineCodeSpaceAllocator().Allocate(size)); - if (UNLIKELY(object == nullptr)) { - heap_->ThrowOutOfMemoryError(size, "AllocateMachineCodeSpaceObject"); - return nullptr; - } - } - } - // hclass is a non-movable object - // SUPPRESS_CSA_NEXTLINE(alpha.core.WasteObjHeader) - SetClass(object, hclass); - // OnAllocateEvent checks object for nullptr - // SUPPRESS_CSA_NEXTLINE(alpha.core.CheckObjHeaderTypeRef) - heap_->OnAllocateEvent(reinterpret_cast(object)); - // CSA detects that OnAllocateEven potentionally may trigger GC but in the real situation cannot. - // OnAllocateEven leads to HeapSnapShot class which may allocate an object in JSObject::GetProperty. - // Snapshots doesn't work now so this situation is impossible. - // SUPPRESS_CSA_NEXTLINE(alpha.core.WasteObjHeader) - return object; -} } // namespace panda::ecmascript #endif // ECMASCRIPT_MEM_HEAP_MANAGER_INL_H diff --git a/runtime/mem/mem_manager.cpp b/runtime/mem/mem_manager.cpp index 15614ed376dd089285bb363ba0bbbb0c45fd7b25..538d70935a3c58881139f7274ab52ca5ddabc96e 100644 --- a/runtime/mem/mem_manager.cpp +++ b/runtime/mem/mem_manager.cpp @@ -14,18 +14,11 @@ */ #include "plugins/ecmascript/runtime/mem/mem_manager-inl.h" -#include "plugins/ecmascript/runtime/mem/heap.h" namespace panda::ecmascript { -MemManager::MemManager(Heap *heap) - : heap_(heap), - newSpaceAllocator_(heap->GetNewSpace()), - freeListAllocator_ {FreeListAllocator(heap->GetOldSpace()), FreeListAllocator(heap_->GetNonMovableSpace()), - FreeListAllocator(heap->GetMachineCodeSpace())} +MemManager::MemManager(EcmaVM *vm) { - ASSERT(heap != nullptr); - heap->SetHeapManager(this); - heapManager_ = heap->GetEcmaVM()->GetHeapManager(); - thread_ = heap->GetEcmaVM()->GetAssociatedJSThread(); + heapManager_ = vm->GetHeapManager(); + thread_ = vm->GetAssociatedJSThread(); } } // namespace panda::ecmascript diff --git a/runtime/mem/mem_manager.h b/runtime/mem/mem_manager.h index bfa1bfc929471fd02cf801743f5b2d8754160394..325fd1a600e5b4231ffcdcf1e585c46664a613a8 100644 --- a/runtime/mem/mem_manager.h +++ b/runtime/mem/mem_manager.h @@ -16,15 +16,12 @@ #ifndef ECMASCRIPT_MEM_JS_MEM_MANAGER_H #define ECMASCRIPT_MEM_JS_MEM_MANAGER_H -#include "plugins/ecmascript/runtime/mem/allocator-inl.h" #include "plugins/ecmascript/runtime/js_hclass.h" namespace panda::ecmascript { -class Heap; - class MemManager { public: - explicit MemManager(Heap *heap); + explicit MemManager(EcmaVM *vm); ~MemManager() = default; NO_COPY_SEMANTIC(MemManager); @@ -37,53 +34,12 @@ public: inline TaggedObject *AllocateNonMovableOrHugeObject(JSHClass *hclass); inline TaggedObject *AllocateHugeObject(JSHClass *hclass, size_t size); inline TaggedObject *AllocateOldGenerationOrHugeObject(JSHClass *hclass, size_t size); - inline TaggedObject *AllocateMachineCodeSpaceObject(JSHClass *hclass, size_t size); - inline uintptr_t AllocateSnapShotSpace(size_t size); inline void SetClass(TaggedObject *header, JSHClass *hclass); - const Heap *GetHeap() const - { - return heap_; - } - - FreeListAllocator &GetFreeListAllocator(MemSpaceType type) - { - return freeListAllocator_[type]; - } - - inline FreeListAllocator &GetOldSpaceAllocator() - { - return freeListAllocator_[OLD_SPACE]; - } - - BumpPointerAllocator &GetNewSpaceAllocator() - { - return newSpaceAllocator_; - } - - inline FreeListAllocator &GetNonMovableSpaceAllocator() - { - return freeListAllocator_[NON_MOVABLE]; - } - - const BumpPointerAllocator &GetSnapShotSpaceAllocator() const - { - return snapshotSpaceAllocator_; - } - - inline FreeListAllocator &GetMachineCodeSpaceAllocator() - { - return freeListAllocator_[MACHINE_CODE_SPACE]; - } - private: - Heap *heap_ {nullptr}; mem::HeapManager *heapManager_; ManagedThread *thread_; - BumpPointerAllocator newSpaceAllocator_; - std::array freeListAllocator_; - BumpPointerAllocator snapshotSpaceAllocator_; }; } // namespace panda::ecmascript diff --git a/runtime/mem/mix_space_collector.cpp b/runtime/mem/mix_space_collector.cpp deleted file mode 100644 index e16095a7efcfd132d8f941d90cd6f695492ea271..0000000000000000000000000000000000000000 --- a/runtime/mem/mix_space_collector.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/mix_space_collector.h" - -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/mem/barriers-inl.h" -#include "plugins/ecmascript/runtime/mem/clock_scope.h" -#include "plugins/ecmascript/runtime/mem/concurrent_marker.h" -#include "plugins/ecmascript/runtime/mem/mem_manager.h" -#include "plugins/ecmascript/runtime/mem/heap-inl.h" -#include "plugins/ecmascript/runtime/mem/object_xray-inl.h" -#include "plugins/ecmascript/runtime/mem/mark_stack.h" -#include "plugins/ecmascript/runtime/mem/mem.h" -#include "plugins/ecmascript/runtime/mem/parallel_evacuation.h" -#include "plugins/ecmascript/runtime/mem/parallel_marker-inl.h" -#include "plugins/ecmascript/runtime/mem/space-inl.h" -#include "plugins/ecmascript/runtime/runtime_call_id.h" -#include "plugins/ecmascript/runtime/vmstat/runtime_stat.h" - -namespace panda::ecmascript { -MixSpaceCollector::MixSpaceCollector(Heap *heap) : heap_(heap), workList_(heap->GetWorkList()) {} - -void MixSpaceCollector::RunPhases() -{ - [[maybe_unused]] ecmascript::JSThread *thread = heap_->GetEcmaVM()->GetJSThread(); - INTERPRETER_TRACE(thread, MixSpaceCollector_RunPhases); - ClockScope clockScope; - - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "MixSpaceCollector::RunPhases"); - concurrentMark_ = heap_->CheckConcurrentMark(thread); - ECMA_GC_LOG() << "concurrentMark_" << concurrentMark_; - InitializePhase(); - MarkingPhase(); - EvacuaPhases(); - SweepPhases(); - heap_->GetEvacuation()->Finalize(); - FinishPhase(); - heap_->GetEcmaVM()->GetEcmaGCStats()->StatisticOldCollector(clockScope.GetPauseTime(), freeSize_, - oldSpaceCommitSize_, nonMoveSpaceCommitSize_); - ECMA_GC_LOG() << "MixSpaceCollector::RunPhases " << clockScope.TotalSpentTime(); -} - -void MixSpaceCollector::InitializePhase() -{ - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "MixSpaceCollector::InitializePhase"); - if (!concurrentMark_) { - heap_->Prepare(); - if (!heap_->IsSemiMarkNeeded() && heap_->GetSweeper()->CanSelectCset()) { - const_cast(heap_->GetOldSpace())->SelectCSet(); - } - heap_->EnumerateRegions([](Region *current) { - // ensure mark bitmap - auto bitmap = current->GetMarkBitmap(); - if (bitmap == nullptr) { - current->GetOrCreateMarkBitmap(); - } else { - bitmap->ClearAllBits(); - } - auto rememberset = current->GetCrossRegionRememberedSet(); - if (rememberset != nullptr) { - rememberset->ClearAllBits(); - } - current->SetMarking(false); - }); - if (heap_->IsSemiMarkNeeded()) { - heap_->EnumerateNewSpaceRegions([](Region *current) { current->ResetAliveObject(); }); - } else { - heap_->EnumerateRegions([](Region *current) { current->ResetAliveObject(); }); - } - workList_->Initialize(TriggerGCType::OLD_GC, ParallelGCTaskPhase::OLD_HANDLE_GLOBAL_POOL_TASK); - - freeSize_ = 0; - hugeSpaceFreeSize_ = 0; - oldSpaceCommitSize_ = heap_->GetOldSpace()->GetCommittedSize(); - nonMoveSpaceCommitSize_ = heap_->GetNonMovableSpace()->GetCommittedSize(); - } -} - -void MixSpaceCollector::FinishPhase() -{ - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "MixSpaceCollector::FinishPhase"); - if (concurrentMark_) { - auto marker = heap_->GetConcurrentMarker(); - marker->Reset(false); - } else { - size_t aliveSize = 0; - workList_->Finish(aliveSize); - heap_->EnumerateRegions([](Region *current) { current->ClearFlag(RegionFlags::IS_IN_PROMOTE_SET); }); - } -} - -void MixSpaceCollector::MarkingPhase() -{ - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "MixSpaceCollector::MarkingPhase"); - if (concurrentMark_) { - [[maybe_unused]] ClockScope scope; - heap_->GetConcurrentMarker()->ReMarking(); - return; - } - heap_->GetNonMovableMarker()->MarkRoots(0); - if (heap_->IsSemiMarkNeeded()) { - heap_->GetNonMovableMarker()->ProcessOldToNew(0); - } else { - heap_->GetNonMovableMarker()->ProcessMarkStack(0); - } - heap_->WaitRunningTaskFinished(); -} - -void MixSpaceCollector::SweepPhases() -{ - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "MixSpaceCollector::SweepPhases"); - if (!heap_->IsSemiMarkNeeded()) { - heap_->GetSweeper()->SweepPhases(); - } -} - -void MixSpaceCollector::EvacuaPhases() -{ - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "MixSpaceCollector::EvacuaPhases"); - heap_->GetEvacuation()->Evacuate(); -} -} // namespace panda::ecmascript diff --git a/runtime/mem/mix_space_collector.h b/runtime/mem/mix_space_collector.h deleted file mode 100644 index 59031fec9cc6fe8b9d09ce562f38fbb4f57fee67..0000000000000000000000000000000000000000 --- a/runtime/mem/mix_space_collector.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_OLD_SAPACE_COLLECTOR_H -#define ECMASCRIPT_MEM_OLD_SAPACE_COLLECTOR_H - -#include "plugins/ecmascript/runtime/mem/mem.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/allocator.h" -#include "plugins/ecmascript/runtime/mem/mark_stack-inl.h" -#include "plugins/ecmascript/runtime/mem/mark_word.h" -#include "plugins/ecmascript/runtime/mem/parallel_work_helper.h" -#include "plugins/ecmascript/runtime/mem/slots.h" -#include "plugins/ecmascript/runtime/mem/object_xray.h" -#include "plugins/ecmascript/runtime/mem/remembered_set.h" -#include "plugins/ecmascript/runtime/mem/semi_space_collector.h" - -namespace panda::ecmascript { -class Heap; -class JSHClass; - -class MixSpaceCollector : public GarbageCollector { -public: - explicit MixSpaceCollector(Heap *heap); - ~MixSpaceCollector() override = default; - NO_COPY_SEMANTIC(MixSpaceCollector); - NO_MOVE_SEMANTIC(MixSpaceCollector); - void RunPhases(); - - Heap *GetHeap() const - { - return heap_; - } - -private: - void InitializePhase(); - void MarkingPhase(); - void SweepPhases(); - void EvacuaPhases(); - void FinishPhase(); - - Heap *heap_; - size_t freeSize_ {0}; - size_t hugeSpaceFreeSize_ = 0; - size_t oldSpaceCommitSize_ = 0; - size_t nonMoveSpaceCommitSize_ = 0; - bool concurrentMark_ {false}; - // obtain from heap - WorkerHelper *workList_ {nullptr}; - - friend class WorkerHelper; - friend class Heap; -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_OLD_SAPACE_COLLECTOR_H diff --git a/runtime/mem/parallel_evacuation-inl.h b/runtime/mem/parallel_evacuation-inl.h deleted file mode 100644 index 5219e799fd1f4ec8efd07de4348cae7852c77aac..0000000000000000000000000000000000000000 --- a/runtime/mem/parallel_evacuation-inl.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_PARALLEL_EVACUATION_INL_H -#define ECMASCRIPT_MEM_PARALLEL_EVACUATION_INL_H - -#include "plugins/ecmascript/runtime/mem/parallel_evacuation.h" - -#include "plugins/ecmascript/runtime/mem/evacuation_allocator-inl.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/region-inl.h" -#include "plugins/ecmascript/runtime/mem/remembered_set.h" -#include "plugins/ecmascript/runtime/platform/platform.h" -#include "mark_word.h" - -namespace panda::ecmascript { -bool ParallelEvacuation::IsPromoteComplete(Region *region) -{ - return (static_cast(region->AliveObject()) / DEFAULT_REGION_SIZE) > MIN_OBJECT_SURVIVAL_RATE && - !region->HasAgeMark(); -} - -bool ParallelEvacuation::UpdateObjectSlot(ObjectSlot &slot) -{ - JSTaggedValue value(slot.GetTaggedType()); - if (value.IsHeapObject()) { - if (value.IsWeak()) { - return UpdateWeakObjectSlot(value.GetTaggedWeakRef(), slot); - } - TaggedObject *object = value.GetTaggedObject(); - MarkWord markWord(object); - if (markWord.IsForwardingAddress()) { - TaggedObject *dst = markWord.ToForwardingAddress(); - slot.Update(dst); - } - return true; - } - return false; -} - -bool ParallelEvacuation::UpdateWeakObjectSlot(TaggedObject *value, ObjectSlot &slot) -{ - Region *objectRegion = Region::ObjectAddressToRange(value); - if (objectRegion->InYoungAndCSetGeneration() && !objectRegion->InPromoteSet()) { - MarkWord markWord(value); - if (markWord.IsForwardingAddress()) { - TaggedObject *dst = markWord.ToForwardingAddress(); - auto weakRef = JSTaggedValue(JSTaggedValue(dst).CreateAndGetWeakRef()).GetRawTaggedObject(); - slot.Update(weakRef); - return true; - } - slot.Update(static_cast(JSTaggedValue::Undefined().GetRawData())); - return false; - } - if (!heap_->IsSemiMarkNeeded() || objectRegion->InPromoteSet()) { - auto markBitmap = objectRegion->GetOrCreateMarkBitmap(); - if (!markBitmap->Test(value)) { - slot.Update(static_cast(JSTaggedValue::Undefined().GetRawData())); - return false; - } - } - return true; -} - -std::unique_ptr ParallelEvacuation::GetFragmentSafe() -{ - os::memory::LockHolder holder(mutex_); - std::unique_ptr unit; - if (!fragments_.empty()) { - unit = std::move(fragments_.back()); - fragments_.pop_back(); - } - return unit; -} - -void ParallelEvacuation::AddFragment(std::unique_ptr region) -{ - fragments_.emplace_back(std::move(region)); -} - -void ParallelEvacuation::AddSweptRegionSafe(Region *region) -{ - os::memory::LockHolder holder(mutex_); - sweptList_.emplace_back(region); -} - -void ParallelEvacuation::FillSweptRegion() -{ - while (!sweptList_.empty()) { - Region *region = sweptList_.back(); - sweptList_.pop_back(); - region->EnumerateKinds([this](FreeObjectKind *kind) { - if (kind == nullptr || kind->Empty()) { - return; - } - evacuationAllocator_->FillFreeList(kind); - }); - } -} - -int ParallelEvacuation::CalculateEvacuationThreadNum() -{ - int length = fragments_.size(); - int regionPerThread = 8; - return std::min(std::max(1, length / regionPerThread), - static_cast(Platform::GetCurrentPlatform()->GetTotalThreadNum())); -} - -int ParallelEvacuation::CalculateUpdateThreadNum() -{ - int length = fragments_.size(); - double regionPerThread = 1.0 / 4; - length = static_cast(std::pow(length, regionPerThread)); - return std::min(std::max(1, length), static_cast(Platform::GetCurrentPlatform()->GetTotalThreadNum())); -} -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_PARALLEL_EVACUATION_INL_H diff --git a/runtime/mem/parallel_evacuation.cpp b/runtime/mem/parallel_evacuation.cpp deleted file mode 100644 index 81e1da51990c758dab1265576ff13379cac6d553..0000000000000000000000000000000000000000 --- a/runtime/mem/parallel_evacuation.cpp +++ /dev/null @@ -1,521 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/parallel_evacuation-inl.h" - -#include "plugins/ecmascript/runtime/js_hclass-inl.h" -#include "plugins/ecmascript/runtime/mem/barriers-inl.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/object_xray-inl.h" -#include "plugins/ecmascript/runtime/mem/space-inl.h" -#include "plugins/ecmascript/runtime/mem/mem.h" -#include "plugins/ecmascript/runtime/mem/tlab_allocator-inl.h" - -#ifndef __clang_analyzer__ - -namespace panda::ecmascript { -void ParallelEvacuation::Initialize() -{ - evacuationAllocator_->Initialize(TriggerGCType::OLD_GC); - allocator_ = new TlabAllocator(heap_, TriggerGCType::COMPRESS_FULL_GC); - ageMark_ = heap_->GetFromSpace()->GetAgeMark(); -} - -void ParallelEvacuation::Finalize() -{ - delete allocator_; - evacuationAllocator_->Finalize(TriggerGCType::OLD_GC); -} - -void ParallelEvacuation::Evacuate() -{ - ClockScope clockScope; - Initialize(); - EvacuateSpace(); - UpdateReference(); -} - -void ParallelEvacuation::EvacuateSpace() -{ - heap_->GetFromSpace()->EnumerateRegions( - [this](Region *current) { AddFragment(std::make_unique(this, current)); }); - if (!heap_->IsSemiMarkNeeded()) { - heap_->GetOldSpace()->EnumerateCollectRegionSet( - [this](Region *current) { AddFragment(std::make_unique(this, current)); }); - } - if (heap_->IsParallelGCEnabled()) { - os::memory::LockHolder holder(mutex_); - parallel_ = CalculateEvacuationThreadNum(); - for (int i = 0; i < parallel_; i++) { - Platform::GetCurrentPlatform()->PostTask(std::make_unique(this)); - } - } - - EvacuateSpace(allocator_, true); - WaitFinished(); -} - -bool ParallelEvacuation::EvacuateSpace(TlabAllocator *allocator, bool isMain) -{ - std::unique_ptr region = GetFragmentSafe(); - while (region != nullptr) { - EvacuateRegion(allocator, region->GetRegion()); - region = GetFragmentSafe(); - } - allocator->Finalize(); - if (!isMain) { - os::memory::LockHolder holder(mutex_); - if (--parallel_ <= 0) { - condition_.SignalAll(); - } - } - return true; -} - -void ParallelEvacuation::EvacuateRegion(TlabAllocator *allocator, Region *region) -{ - bool isPromoted = region->BelowAgeMark() || region->InOldGeneration(); - if (IsPromoteComplete(region)) { - bool ret = false; - if (isPromoted) { - if (region->InYoungGeneration()) { - promotedAccumulatorSize_.fetch_add(region->AliveObject()); - } - ret = evacuationAllocator_->AddRegionToOld(region); - } else { - ret = evacuationAllocator_->AddRegionToYoung(region); - if (!ret) { - if (region->InYoungGeneration()) { - promotedAccumulatorSize_.fetch_add(region->AliveObject()); - } - ret = evacuationAllocator_->AddRegionToOld(region); - } - } - if (!ret) { - LOG(FATAL, RUNTIME) << "Add Region failed:"; - } - } else { - auto markBitmap = region->GetOrCreateMarkBitmap(); - ASSERT(markBitmap != nullptr); - markBitmap->IterateOverMarkedChunks([this, ®ion, &isPromoted, &allocator](void *mem) { - ASSERT(region->InRange(ToUintPtr(mem))); - auto header = reinterpret_cast(mem); - auto klass = header->GetClass(); - auto size = klass->SizeFromJSHClass(header); - - uintptr_t address = 0; - if (isPromoted || (region->HasAgeMark() && ToUintPtr(mem) < ageMark_)) { - address = allocator->Allocate(size, SpaceAlloc::OLD_SPACE); - promotedAccumulatorSize_.fetch_add(size); - } else { - address = allocator->Allocate(size, SpaceAlloc::YOUNG_SPACE); - if (address == 0) { - address = allocator->Allocate(size, SpaceAlloc::OLD_SPACE); - promotedAccumulatorSize_.fetch_add(size); - } - } - LOG_IF(address == 0, FATAL, RUNTIME) << "Evacuate object failed:" << size; - - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - if (memcpy_sp(ToVoidPtr(address), size, ToVoidPtr(ToUintPtr(mem)), size) != EOK) { - LOG_ECMA(FATAL) << "memcpy_s failed"; - } - - ObjectAccessor::SetDynValueWithoutBarrier( - header, 0, JSTaggedValue(MarkWord::FromForwardingAddress(address)).GetRawData()); -#if ECMASCRIPT_ENABLE_HEAP_VERIFY - VerifyHeapObject(reinterpret_cast(address)); -#endif - }); - } -} - -void ParallelEvacuation::VerifyHeapObject(TaggedObject *object) -{ - auto klass = object->GetClass(); - objXRay_.VisitObjectBody( - object, klass, [&]([[maybe_unused]] TaggedObject *root, ObjectSlot start, ObjectSlot end) { - for (ObjectSlot slot = start; slot < end; slot++) { - JSTaggedValue value(slot.GetTaggedType()); - if (value.IsHeapObject()) { - if (value.IsWeak()) { - continue; - } - Region *object_region = Region::ObjectAddressToRange(value.GetTaggedObject()); - if (heap_->IsSemiMarkNeeded() && !object_region->InYoungGeneration()) { - continue; - } - auto reset = object_region->GetMarkBitmap(); - if (!reset->Test(value.GetTaggedObject())) { - LOG(FATAL, RUNTIME) << "Miss mark value: " << value.GetTaggedObject() - << ", body address:" << slot.SlotAddress() << ", header address:" << object; - } - } - } - }); -} - -void ParallelEvacuation::UpdateReference() -{ - // Update reference pointers - uint32_t youngeRegionMoveCount = 0; - uint32_t oldRegionMoveCount = 0; - uint32_t youngeRegionCopyCount = 0; - uint32_t oldRegionCopyCount = 0; - heap_->GetNewSpace()->EnumerateRegions([&](Region *current) { - if (current->InPromoteSet()) { - AddFragment(std::make_unique(this, current)); - youngeRegionMoveCount++; - } else { - AddFragment(std::make_unique(this, current)); - youngeRegionCopyCount++; - } - }); - heap_->GetCompressSpace()->EnumerateRegions([&](Region *current) { - if (current->InPromoteSet()) { - AddFragment(std::make_unique(this, current)); - oldRegionMoveCount++; - } else { - AddFragment(std::make_unique(this, current)); - oldRegionCopyCount++; - } - }); - heap_->EnumerateOldSpaceRegions([this](Region *current) { - if (current->InCollectSet()) { - return; - } - AddFragment(std::make_unique(this, current)); - }); - LOG(INFO, RUNTIME) << "UpdatePointers statistic: younge space region compact moving count:" << youngeRegionMoveCount - << "younge space region compact coping count:" << youngeRegionCopyCount - << "old space region compact moving count:" << oldRegionMoveCount - << "old space region compact coping count:" << oldRegionCopyCount; - - // Optimization weak reference for native pointer - UpdateWeakReference(); - if (heap_->IsParallelGCEnabled()) { - os::memory::LockHolder holder(mutex_); - parallel_ = CalculateUpdateThreadNum(); - for (int i = 0; i < parallel_; i++) { - Platform::GetCurrentPlatform()->PostTask(std::make_unique(this)); - } - } - - UpdateRoot(); - ProcessFragments(true); - WaitFinished(); - FillSweptRegion(); -} - -void ParallelEvacuation::UpdateRoot() -{ - RootVisitor gcUpdateYoung = [this]([[maybe_unused]] Root type, ObjectSlot slot) { UpdateObjectSlot(slot); }; - RootRangeVisitor gcUpdateRangeYoung = [this]([[maybe_unused]] Root type, ObjectSlot start, ObjectSlot end) { - for (ObjectSlot slot = start; slot < end; slot++) { - UpdateObjectSlot(slot); - } - }; - - objXRay_.VisitVMRoots(gcUpdateYoung, gcUpdateRangeYoung); -} - -void ParallelEvacuation::UpdateWeakReference() -{ - bool isOnlySemi = heap_->IsSemiMarkNeeded(); - auto stringTable = heap_->GetEcmaVM()->GetEcmaStringTable(); - WeakRootVisitor gcUpdateWeak = [&](TaggedObject *header) { - Region *objectRegion = Region::ObjectAddressToRange(reinterpret_cast(header)); - if (objectRegion->InYoungAndCSetGeneration() && !objectRegion->InPromoteSet()) { - MarkWord markWord(header); - if (markWord.IsForwardingAddress()) { - return markWord.ToForwardingAddress(); - } - return reinterpret_cast(ToUintPtr(nullptr)); - } - if (!isOnlySemi || objectRegion->InPromoteSet()) { - auto markBitmap = objectRegion->GetOrCreateMarkBitmap(); - if (!markBitmap->Test(header)) { - return reinterpret_cast(ToUintPtr(nullptr)); - } - } - return header; - }; - stringTable->SweepWeakReference(gcUpdateWeak); - heap_->GetEcmaVM()->GetJSThread()->IterateWeakEcmaGlobalStorage(gcUpdateWeak); - heap_->GetEcmaVM()->ProcessReferences(gcUpdateWeak); -} - -void ParallelEvacuation::UpdateRSet(Region *region) -{ - auto rememberedSet = region->GetOldToNewRememberedSet(); - if (LIKELY(rememberedSet != nullptr)) { - rememberedSet->IterateOverMarkedChunks([this, rememberedSet](void *mem) -> bool { - ObjectSlot slot(ToUintPtr(mem)); - if (UpdateObjectSlot(slot)) { - Region *valueRegion = Region::ObjectAddressToRange(slot.GetTaggedObjectHeader()); - if (!valueRegion->InYoungGeneration()) { - rememberedSet->Clear(slot.SlotAddress()); - } - } - return true; - }); - } - if (!heap_->IsSemiMarkNeeded()) { - rememberedSet = region->GetCrossRegionRememberedSet(); - if (LIKELY(rememberedSet != nullptr)) { - rememberedSet->IterateOverMarkedChunks([this](void *mem) -> bool { - ObjectSlot slot(ToUintPtr(mem)); - UpdateObjectSlot(slot); - return true; - }); - rememberedSet->ClearAllBits(); - } - } -} - -void ParallelEvacuation::UpdateCompressRegionReference(Region *region) -{ - auto curPtr = region->GetBegin(); - auto endPtr = region->GetEnd(); - auto rset = region->GetOldToNewRememberedSet(); - if (rset != nullptr) { - rset->ClearAllBits(); - } - - size_t objSize = 0; - while (curPtr < endPtr) { - auto freeObject = FreeObject::Cast(curPtr); - if (!freeObject->IsFreeObject()) { - auto obj = reinterpret_cast(curPtr); - auto klass = obj->GetClass(); - if (klass->HasReferenceField()) { - UpdateCompressObjectField(region, obj, klass); - } - objSize = klass->SizeFromJSHClass(obj); - } else { - objSize = freeObject->Available(); - } - curPtr += objSize; - CHECK_OBJECT_SIZE(objSize); - } - CHECK_REGION_END(curPtr, endPtr); -} - -void ParallelEvacuation::UpdateNewRegionReference(Region *region) -{ - Region *current = heap_->GetNewSpace()->GetCurrentRegion(); - auto curPtr = region->GetBegin(); - uintptr_t endPtr; - if (region == current) { - auto top = evacuationAllocator_->GetNewSpaceTop(); - endPtr = curPtr + region->GetAllocatedBytes(top); - } else { - endPtr = curPtr + region->GetAllocatedBytes(); - } - - size_t objSize = 0; - while (curPtr < endPtr) { - auto freeObject = FreeObject::Cast(curPtr); - if (!freeObject->IsFreeObject()) { - auto obj = reinterpret_cast(curPtr); - auto klass = obj->GetClass(); - if (klass->HasReferenceField()) { - UpdateNewObjectField(obj, klass); - } - objSize = klass->SizeFromJSHClass(obj); - } else { - objSize = freeObject->Available(); - } - curPtr += objSize; - CHECK_OBJECT_SIZE(objSize); - } - CHECK_REGION_END(curPtr, endPtr); -} - -void ParallelEvacuation::UpdateAndSweepNewRegionReference(Region *region) -{ - auto markBitmap = region->GetMarkBitmap(); - uintptr_t freeStart = region->GetBegin(); - uintptr_t freeEnd = freeStart + region->GetAllocatedBytes(); - if (markBitmap != nullptr) { - markBitmap->IterateOverMarkedChunks([this, ®ion, &freeStart](void *mem) { - ASSERT(region->InRange(ToUintPtr(mem))); - (void)region; - auto header = reinterpret_cast(mem); - JSHClass *klass = header->GetClass(); - if (klass->HasReferenceField()) { - UpdateNewObjectField(header, klass); - } - - uintptr_t fEnd = ToUintPtr(mem); - if (freeStart != fEnd) { - FreeObject::FillFreeObject(heap_->GetEcmaVM(), freeStart, fEnd - freeStart); - } - - freeStart = fEnd + klass->SizeFromJSHClass(header); - }); - } - CHECK_REGION_END(freeStart, freeEnd); - if (freeStart < freeEnd) { - FreeObject::FillFreeObject(heap_->GetEcmaVM(), freeStart, freeEnd - freeStart); - } -} - -void ParallelEvacuation::UpdateAndSweepCompressRegionReference(Region *region, bool isMain) -{ - auto markBitmap = region->GetMarkBitmap(); - auto rset = region->GetOldToNewRememberedSet(); - if (rset != nullptr) { - rset->ClearAllBits(); - } - uintptr_t freeStart = region->GetBegin(); - if (markBitmap != nullptr) { - markBitmap->IterateOverMarkedChunks([this, ®ion, &freeStart, &isMain](void *mem) { - ASSERT(region->InRange(ToUintPtr(mem))); - ASSERT(!FreeObject::Cast(ToUintPtr(mem))->IsFreeObject()); - auto header = reinterpret_cast(mem); - auto klass = header->GetClass(); - ObjectSlot slot(ToUintPtr(&klass)); - UpdateObjectSlot(slot); - if (klass->HasReferenceField()) { - UpdateCompressObjectField(region, header, klass); - } - - uintptr_t freeEnd = ToUintPtr(mem); - if (freeStart != freeEnd) { - evacuationAllocator_->Free(freeStart, freeEnd, isMain); - } - freeStart = freeEnd + klass->SizeFromJSHClass(header); - }); - } - uintptr_t freeEnd = region->GetEnd(); - CHECK_REGION_END(freeStart, freeEnd); - if (freeStart < freeEnd) { - evacuationAllocator_->Free(freeStart, freeEnd, isMain); - } - if (!isMain) { - AddSweptRegionSafe(region); - } -} - -void ParallelEvacuation::UpdateNewObjectField(TaggedObject *object, JSHClass *cls) -{ - objXRay_.VisitObjectBody( - object, cls, [this]([[maybe_unused]] TaggedObject *root, ObjectSlot start, ObjectSlot end) { - for (ObjectSlot slot = start; slot < end; slot++) { - UpdateObjectSlot(slot); - } - }); -} - -void ParallelEvacuation::UpdateCompressObjectField(Region *region, TaggedObject *object, JSHClass *cls) -{ - objXRay_.VisitObjectBody( - object, cls, [this, region]([[maybe_unused]] TaggedObject *root, ObjectSlot start, ObjectSlot end) { - for (ObjectSlot slot = start; slot < end; slot++) { - if (UpdateObjectSlot(slot)) { - Region *valueRegion = Region::ObjectAddressToRange(slot.GetTaggedObjectHeader()); - if (valueRegion->InYoungGeneration()) { - region->InsertOldToNewRememberedSet(slot.SlotAddress()); - } - } - } - }); -} - -void ParallelEvacuation::WaitFinished() -{ - if (parallel_ > 0) { - os::memory::LockHolder holder(mutex_); - while (parallel_ > 0) { - condition_.Wait(&mutex_); - } - } -} - -bool ParallelEvacuation::ProcessFragments(bool isMain) -{ - std::unique_ptr region = GetFragmentSafe(); - while (region != nullptr) { - region->Process(isMain); - region = GetFragmentSafe(); - } - if (!isMain) { - os::memory::LockHolder holder(mutex_); - if (--parallel_ <= 0) { - condition_.SignalAll(); - } - } - return true; -} - -ParallelEvacuation::EvacuationTask::EvacuationTask(ParallelEvacuation *evacuation) : evacuation_(evacuation) -{ - allocator_ = new TlabAllocator(evacuation->heap_, TriggerGCType::COMPRESS_FULL_GC); -} - -ParallelEvacuation::EvacuationTask::~EvacuationTask() -{ - allocator_->Finalize(); - delete allocator_; -} - -bool ParallelEvacuation::EvacuationTask::Run([[maybe_unused]] uint32_t threadIndex) -{ - return evacuation_->EvacuateSpace(allocator_); -} - -bool ParallelEvacuation::UpdateReferenceTask::Run([[maybe_unused]] uint32_t threadIndex) -{ - evacuation_->ProcessFragments(false); - return true; -} - -bool ParallelEvacuation::EvacuationFragment::Process([[maybe_unused]] bool isMain) -{ - return true; -} - -bool ParallelEvacuation::UpdateRSetFragment::Process([[maybe_unused]] bool isMain) -{ - GetEvacuation()->UpdateRSet(GetRegion()); - return true; -} - -bool ParallelEvacuation::UpdateNewRegionFragment::Process([[maybe_unused]] bool isMain) -{ - GetEvacuation()->UpdateNewRegionReference(GetRegion()); - return true; -} - -bool ParallelEvacuation::UpdateCompressRegionFragment::Process([[maybe_unused]] bool isMain) -{ - GetEvacuation()->UpdateCompressRegionReference(GetRegion()); - return true; -} - -bool ParallelEvacuation::UpdateAndSweepNewRegionFragment::Process([[maybe_unused]] bool isMain) -{ - GetEvacuation()->UpdateAndSweepNewRegionReference(GetRegion()); - return true; -} - -bool ParallelEvacuation::UpdateAndSweepCompressRegionFragment::Process(bool isMain) -{ - GetEvacuation()->UpdateAndSweepCompressRegionReference(GetRegion(), isMain); - return true; -} -} // namespace panda::ecmascript -#endif // __clang_analyzer__ diff --git a/runtime/mem/parallel_evacuation.h b/runtime/mem/parallel_evacuation.h deleted file mode 100644 index 7ac8170d409a017c9910a44365a1675ca333e406..0000000000000000000000000000000000000000 --- a/runtime/mem/parallel_evacuation.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_PARALLEL_EVACUATION_H -#define ECMASCRIPT_MEM_PARALLEL_EVACUATION_H - -#include -#include - -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/object_xray.h" -#include "plugins/ecmascript/runtime/mem/region.h" -#include "plugins/ecmascript/runtime/mem/remembered_set.h" -#include "plugins/ecmascript/runtime/mem/space.h" -#include "plugins/ecmascript/runtime/mem/tagged_object.h" -#include "plugins/ecmascript/runtime/platform/task.h" -#include "os/mutex.h" - -namespace panda::ecmascript { -class JSHClass; -class TlabAllocator; - -class ParallelEvacuation { -public: - explicit ParallelEvacuation(Heap *heap) - : heap_(heap), objXRay_(heap->GetEcmaVM()), evacuationAllocator_(heap_->GetEvacuationAllocator()) - { - } - ~ParallelEvacuation() = default; - void Initialize(); - void Finalize(); - void Evacuate(); - - size_t GetPromotedAccumulatorSize() const - { - return promotedAccumulatorSize_; - } - - NO_COPY_SEMANTIC(ParallelEvacuation); - NO_MOVE_SEMANTIC(ParallelEvacuation); - -private: - static constexpr double MIN_OBJECT_SURVIVAL_RATE = 0.8; - - class EvacuationTask : public Task { - public: - explicit EvacuationTask(ParallelEvacuation *evacuation); - ~EvacuationTask() override; - bool Run(uint32_t threadIndex) override; - - NO_COPY_SEMANTIC(EvacuationTask); - NO_MOVE_SEMANTIC(EvacuationTask); - - private: - ParallelEvacuation *evacuation_ {nullptr}; - TlabAllocator *allocator_ {nullptr}; - }; - - class UpdateReferenceTask : public Task { - public: - explicit UpdateReferenceTask(ParallelEvacuation *evacuation) : evacuation_(evacuation) {}; - ~UpdateReferenceTask() override = default; - - bool Run(uint32_t threadIndex) override; - - NO_COPY_SEMANTIC(UpdateReferenceTask); - NO_MOVE_SEMANTIC(UpdateReferenceTask); - - private: - ParallelEvacuation *evacuation_; - }; - - class Fragment { - public: - Fragment(ParallelEvacuation *evacuation, Region *region) : evacuation_(evacuation), region_(region) {}; - virtual ~Fragment() = default; - virtual bool Process(bool isMain) = 0; - inline Region *GetRegion() - { - return region_; - } - - inline ParallelEvacuation *GetEvacuation() - { - return evacuation_; - } - - NO_COPY_SEMANTIC(Fragment); - NO_MOVE_SEMANTIC(Fragment); - - protected: - ParallelEvacuation *evacuation_; // NOLINT(misc-non-private-member-variables-in-classes) - Region *region_; // NOLINT(misc-non-private-member-variables-in-classes) - }; - - class EvacuationFragment : public Fragment { - public: - EvacuationFragment(ParallelEvacuation *evacuation, Region *region) : Fragment(evacuation, region) {} - bool Process(bool isMain) override; - }; - - class UpdateRSetFragment : public Fragment { - public: - UpdateRSetFragment(ParallelEvacuation *evacuation, Region *region) : Fragment(evacuation, region) {} - bool Process(bool isMain) override; - }; - - class UpdateNewRegionFragment : public Fragment { - public: - UpdateNewRegionFragment(ParallelEvacuation *evacuation, Region *region) : Fragment(evacuation, region) {} - bool Process(bool isMain) override; - }; - - class UpdateCompressRegionFragment : public Fragment { - public: - UpdateCompressRegionFragment(ParallelEvacuation *evacuation, Region *region) : Fragment(evacuation, region) {} - bool Process(bool isMain) override; - }; - - class UpdateAndSweepNewRegionFragment : public Fragment { - public: - UpdateAndSweepNewRegionFragment(ParallelEvacuation *evacuation, Region *region) : Fragment(evacuation, region) - { - } - bool Process(bool isMain) override; - }; - - class UpdateAndSweepCompressRegionFragment : public Fragment { - public: - UpdateAndSweepCompressRegionFragment(ParallelEvacuation *evacuation, Region *region) - : Fragment(evacuation, region) - { - } - bool Process(bool isMain) override; - }; - - bool ProcessFragments(bool isMain = false); - - void EvacuateSpace(); - bool EvacuateSpace(TlabAllocator *allocator, bool isMain = false); - void EvacuateRegion(TlabAllocator *allocator, Region *region); - - inline bool IsPromoteComplete(Region *region); - void VerifyHeapObject(TaggedObject *object); - - void UpdateReference(); - void UpdateRoot(); - void UpdateWeakReference(); - void UpdateRSet(Region *region); - void UpdateNewRegionReference(Region *region); - void UpdateCompressRegionReference(Region *region); - void UpdateAndSweepNewRegionReference(Region *region); - void UpdateAndSweepCompressRegionReference(Region *region, bool isMain); - void UpdateNewObjectField(TaggedObject *object, JSHClass *cls); - void UpdateCompressObjectField(Region *region, TaggedObject *object, JSHClass *cls); - - inline bool UpdateObjectSlot(ObjectSlot &slot); - inline bool UpdateWeakObjectSlot(TaggedObject *value, ObjectSlot &slot); - - inline std::unique_ptr GetFragmentSafe(); - inline void AddFragment(std::unique_ptr region); - - inline void AddSweptRegionSafe(Region *region); - inline void FillSweptRegion(); - - inline int CalculateEvacuationThreadNum(); - inline int CalculateUpdateThreadNum(); - void WaitFinished(); - - Heap *heap_; - TlabAllocator *allocator_ {nullptr}; - ObjectXRay objXRay_; - EvacuationAllocator *evacuationAllocator_; - - uintptr_t ageMark_ {0}; - std::vector> fragments_; - std::vector sweptList_; - std::atomic_int parallel_ = 0; - std::atomic promotedAccumulatorSize_ = 0; - os::memory::Mutex mutex_; - os::memory::ConditionVariable condition_; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_PARALLEL_EVACUATION_H diff --git a/runtime/mem/parallel_marker-inl.h b/runtime/mem/parallel_marker-inl.h deleted file mode 100644 index 8ce6b1e4f66b623cf8c8f7bc0645fb9e52c1e998..0000000000000000000000000000000000000000 --- a/runtime/mem/parallel_marker-inl.h +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_PARALLEL_MARKER_INL_H -#define ECMASCRIPT_MEM_PARALLEL_MARKER_INL_H - -#include "plugins/ecmascript/runtime/mem/parallel_marker.h" - -#include "plugins/ecmascript/runtime/js_hclass-inl.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/parallel_work_helper.h" -#include "plugins/ecmascript/runtime/mem/region-inl.h" -#include "plugins/ecmascript/runtime/mem/tlab_allocator-inl.h" - -#include "mem/gc/bitmap.h" - -#ifndef __clang_analyzer__ - -namespace panda::ecmascript { -constexpr int HEAD_SIZE = TaggedObject::TaggedObjectSize(); - -inline void Marker::HandleObjectVisitor(uint32_t threadId, Region *objectRegion, bool needBarrier, - [[maybe_unused]] TaggedObject *root, ObjectSlot start, ObjectSlot end) -{ - for (ObjectSlot slot = start; slot < end; slot++) { - JSTaggedValue value(slot.GetTaggedType()); - if (!value.IsHeapObject()) { - continue; - } - - TaggedObject *obj = nullptr; - if (!value.IsWeak()) { - obj = value.GetTaggedObject(); - MarkObject(threadId, obj); - } else { - obj = value.GetWeakReferentUnChecked(); - } - - if (!needBarrier) { - continue; - } - - Region *valueRegion = Region::ObjectAddressToRange(obj); - if (valueRegion->InCollectSet()) { - objectRegion->AtomicInsertCrossRegionRememberedSet(slot.SlotAddress()); - } - } -} - -inline void Marker::HandleMoveObjectVisitor(uint32_t threadId, bool promoted, TaggedObject *root, ObjectSlot start, - ObjectSlot end) -{ - for (ObjectSlot slot = start; slot < end; slot++) { - JSTaggedValue value(slot.GetTaggedType()); - if (value.IsHeapObject()) { - if (value.IsWeak()) { - RecordWeakReference(threadId, reinterpret_cast(slot.SlotAddress())); - continue; - } - auto slotStatus = MarkObject(threadId, value.GetTaggedObject(), slot); - if (promoted && slotStatus == SlotStatus::KEEP_SLOT) { - SlotNeedUpdate waitUpdate(reinterpret_cast(root), slot); - heap_->GetWorkList()->PushWaitUpdateSlot(threadId, waitUpdate); - } - } - } -} - -inline void NonMovableMarker::MarkObject(uint32_t threadId, TaggedObject *object) -{ - Region *objectRegion = Region::ObjectAddressToRange(object); - - if (heap_->IsSemiMarkNeeded() && !objectRegion->InYoungGeneration()) { - return; - } - - auto markBitmap = objectRegion->GetOrCreateMarkBitmap(); - if (!markBitmap->AtomicTestAndSet(object)) { - heap_->GetWorkList()->Push(threadId, object, objectRegion); - } -} - -inline void NonMovableMarker::HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) -{ - JSTaggedValue value(slot.GetTaggedType()); - if (value.IsHeapObject()) { - MarkObject(threadId, value.GetTaggedObject()); - } -} - -inline void NonMovableMarker::HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, - ObjectSlot end) -{ - for (ObjectSlot slot = start; slot < end; slot++) { - JSTaggedValue value(slot.GetTaggedType()); - if (value.IsHeapObject()) { - MarkObject(threadId, value.GetTaggedObject()); - } - } -} - -inline void NonMovableMarker::HandleOldToNewRSet(uint32_t threadId, Region *region) -{ - auto oldRSet = region->GetOldToNewRememberedSet(); - if (LIKELY(oldRSet != nullptr)) { - oldRSet->IterateOverMarkedChunks([this, threadId](void *mem) -> bool { - ObjectSlot slot(ToUintPtr(mem)); - JSTaggedValue value(slot.GetTaggedType()); - if (value.IsHeapObject() && !value.IsWeak()) { - MarkObject(threadId, value.GetTaggedObject()); - } - return true; - }); - } -} - -inline void NonMovableMarker::RecordWeakReference(uint32_t threadId, JSTaggedType *ref) -{ - Region *objectRegion = Region::ObjectAddressToRange(reinterpret_cast(ref)); - if (!objectRegion->InYoungGeneration()) { - heap_->GetWorkList()->PushWeakReference(threadId, ref); - } -} - -inline void MovableMarker::HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) -{ - JSTaggedValue value(slot.GetTaggedType()); - if (value.IsHeapObject()) { - MarkObject(threadId, value.GetTaggedObject(), slot); - } -} - -inline void MovableMarker::HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, - ObjectSlot end) -{ - for (ObjectSlot slot = start; slot < end; slot++) { - JSTaggedValue value(slot.GetTaggedType()); - if (value.IsHeapObject()) { - MarkObject(threadId, value.GetTaggedObject(), slot); - } - } -} - -inline void MovableMarker::HandleOldToNewRSet(uint32_t threadId, Region *region) -{ - auto oldRSet = region->GetOldToNewRememberedSet(); - if (LIKELY(oldRSet != nullptr)) { - oldRSet->IterateOverMarkedChunks([this, &oldRSet, threadId](void *mem) -> bool { - ObjectSlot slot(ToUintPtr(mem)); - JSTaggedValue value(slot.GetTaggedType()); - if (value.IsHeapObject()) { - if (value.IsWeak()) { - RecordWeakReference(threadId, reinterpret_cast(mem)); - return true; - } - auto slotStatus = MarkObject(threadId, value.GetTaggedObject(), slot); - if (slotStatus == SlotStatus::CLEAR_SLOT) { - oldRSet->Clear(ToUintPtr(mem)); - } - } - return true; - }); - } -} - -inline uintptr_t MovableMarker::AllocateDstSpace(uint32_t threadId, size_t size, bool &shouldPromote) -{ - uintptr_t forwardAddress = 0; - if (shouldPromote) { - forwardAddress = heap_->GetWorkList()->GetTlabAllocator(threadId)->Allocate(size, SpaceAlloc::OLD_SPACE); - if (UNLIKELY(forwardAddress == 0)) { - LOG_ECMA_MEM(FATAL) << "EvacuateObject alloc failed: " - << " size: " << size; - UNREACHABLE(); - } - } else { - forwardAddress = heap_->GetWorkList()->GetTlabAllocator(threadId)->Allocate(size, SpaceAlloc::YOUNG_SPACE); - if (UNLIKELY(forwardAddress == 0)) { - forwardAddress = heap_->GetWorkList()->GetTlabAllocator(threadId)->Allocate(size, SpaceAlloc::OLD_SPACE); - if (UNLIKELY(forwardAddress == 0)) { - LOG_ECMA_MEM(FATAL) << "EvacuateObject alloc failed: " - << " size: " << size; - UNREACHABLE(); - } - shouldPromote = true; - } - } - return forwardAddress; -} - -inline void MovableMarker::UpdateForwardAddressIfSuccess(uint32_t threadId, TaggedObject *object, JSHClass *klass, - uintptr_t toAddress, size_t size, const MarkWord &markWord, - ObjectSlot slot) -{ - CopyObjectWithoutHeader(object, toAddress, size); - heap_->GetWorkList()->AddAliveSize(threadId, size); - *reinterpret_cast(toAddress) = markWord.GetValue(); - heap_->OnMoveEvent(reinterpret_cast(object), toAddress); - if (klass->HasReferenceField()) { - heap_->GetWorkList()->Push(threadId, reinterpret_cast(toAddress)); - } - slot.Update(reinterpret_cast(toAddress)); -} - -inline bool MovableMarker::UpdateForwardAddressIfFailed(TaggedObject *object, uintptr_t toAddress, size_t size, - ObjectSlot slot) -{ - FreeObject::FillFreeObject(heap_->GetEcmaVM(), toAddress, size); - TaggedObject *dst = MarkWord(object).ToForwardingAddress(); - slot.Update(dst); - return Region::ObjectAddressToRange(dst)->InYoungGeneration(); -} - -inline void MovableMarker::CopyObjectWithoutHeader(TaggedObject *object, uintptr_t toAddress, size_t size) -{ - if (memcpy_s(ToVoidPtr(toAddress + HEAD_SIZE), size - HEAD_SIZE, ToVoidPtr(ToUintPtr(object) + HEAD_SIZE), - size - HEAD_SIZE) != EOK) { - LOG_ECMA_MEM(FATAL) << "CopyObjectWithoutHeader memcpy_s failed: " - << " dst: " << toAddress << " src: " << ToUintPtr(object) << " size: " << size; - UNREACHABLE(); - } -} - -inline SlotStatus SemiGcMarker::MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot slot) -{ - Region *objectRegion = Region::ObjectAddressToRange(object); - if (!objectRegion->InYoungGeneration()) { - return SlotStatus::CLEAR_SLOT; - } - - MarkWord markWord(object); - if (markWord.IsForwardingAddress()) { - TaggedObject *dst = markWord.ToForwardingAddress(); - slot.Update(dst); - Region *valueRegion = Region::ObjectAddressToRange(dst); - return valueRegion->InYoungGeneration() ? SlotStatus::KEEP_SLOT : SlotStatus::CLEAR_SLOT; - } - return EvacuateObject(threadId, object, markWord, slot); -} - -inline SlotStatus SemiGcMarker::EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, - ObjectSlot slot) -{ - JSHClass *klass = markWord.GetJSHClass(); - size_t size = klass->SizeFromJSHClass(object); - bool isPromoted = ShouldBePromoted(object); - - uintptr_t forwardAddress = AllocateDstSpace(threadId, size, isPromoted); - bool result = Barriers::AtomicSetDynPrimitive(object, 0, markWord.GetValue(), - MarkWord::FromForwardingAddress(forwardAddress)); - if (result) { - UpdateForwardAddressIfSuccess(threadId, object, klass, forwardAddress, size, markWord, slot); - return isPromoted ? SlotStatus::CLEAR_SLOT : SlotStatus::KEEP_SLOT; - } - bool keepSlot = UpdateForwardAddressIfFailed(object, forwardAddress, size, slot); - return keepSlot ? SlotStatus::KEEP_SLOT : SlotStatus::CLEAR_SLOT; -} - -inline bool SemiGcMarker::ShouldBePromoted(TaggedObject *object) -{ - Region *region = Region::ObjectAddressToRange(object); - return (region->BelowAgeMark() || (region->HasAgeMark() && ToUintPtr(object) < ageMark_)); -} - -inline void SemiGcMarker::RecordWeakReference(uint32_t threadId, JSTaggedType *ref) -{ - auto value = JSTaggedValue(*ref); - Region *objectRegion = Region::ObjectAddressToRange(value.GetTaggedWeakRef()); - if (objectRegion->InYoungGeneration()) { - heap_->GetWorkList()->PushWeakReference(threadId, ref); - } -} - -inline SlotStatus CompressGcMarker::MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot slot) -{ - Region *objectRegion = Region::ObjectAddressToRange(object); - if (!objectRegion->InYoungAndOldGeneration()) { - auto markBitmap = objectRegion->GetMarkBitmap(); - if (!markBitmap->AtomicTestAndSet(object)) { - heap_->GetWorkList()->Push(threadId, object); - } - return SlotStatus::CLEAR_SLOT; - } - - MarkWord markWord(object); - if (markWord.IsForwardingAddress()) { - TaggedObject *dst = markWord.ToForwardingAddress(); - slot.Update(dst); - return SlotStatus::CLEAR_SLOT; - } - return EvacuateObject(threadId, object, markWord, slot); -} - -inline SlotStatus CompressGcMarker::EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, - ObjectSlot slot) -{ - JSHClass *klass = markWord.GetJSHClass(); - size_t size = klass->SizeFromJSHClass(object); - bool isPromoted = true; - - uintptr_t forwardAddress = AllocateDstSpace(threadId, size, isPromoted); - bool result = Barriers::AtomicSetDynPrimitive(object, 0, markWord.GetValue(), - MarkWord::FromForwardingAddress(forwardAddress)); - if (result) { - UpdateForwardAddressIfSuccess(threadId, object, klass, forwardAddress, size, markWord, slot); - return SlotStatus::CLEAR_SLOT; - } - UpdateForwardAddressIfFailed(object, forwardAddress, size, slot); - return SlotStatus::CLEAR_SLOT; -} - -inline void CompressGcMarker::RecordWeakReference(uint32_t threadId, JSTaggedType *ref) -{ - heap_->GetWorkList()->PushWeakReference(threadId, ref); -} -} // namespace panda::ecmascript -#endif // __clang_analyzer__ -#endif // ECMASCRIPT_MEM_PARALLEL_MARKER_INL_H diff --git a/runtime/mem/parallel_marker.cpp b/runtime/mem/parallel_marker.cpp deleted file mode 100644 index 928ed0a9bcd261099d152a0a8782fcdfee2d8bb4..0000000000000000000000000000000000000000 --- a/runtime/mem/parallel_marker.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/parallel_marker-inl.h" - -#include "plugins/ecmascript/runtime/mem/object_xray-inl.h" - -#ifndef __clang_analyzer__ - -namespace panda::ecmascript { -Marker::Marker(Heap *heap) : heap_(heap), objXRay_(heap_->GetEcmaVM()) {} - -void Marker::MarkRoots(uint32_t threadId) -{ - objXRay_.VisitVMRoots(std::bind(&Marker::HandleRoots, this, threadId, std::placeholders::_1, std::placeholders::_2), - std::bind(&Marker::HandleRangeRoots, this, threadId, std::placeholders::_1, - std::placeholders::_2, std::placeholders::_3)); - heap_->GetWorkList()->PushWorkNodeToGlobal(threadId, false); -} - -void Marker::ProcessOldToNew(uint32_t threadId) -{ - heap_->EnumerateOldSpaceRegions(std::bind(&Marker::HandleOldToNewRSet, this, threadId, std::placeholders::_1)); - ProcessMarkStack(threadId); -} - -void Marker::ProcessOldToNew(uint32_t threadId, Region *region) -{ - heap_->EnumerateOldSpaceRegions(std::bind(&Marker::HandleOldToNewRSet, this, threadId, std::placeholders::_1), - region); - ProcessMarkStack(threadId); -} - -void Marker::ProcessSnapshotRSet(uint32_t threadId) -{ - heap_->EnumerateSnapShotSpaceRegions(std::bind(&Marker::HandleOldToNewRSet, this, threadId, std::placeholders::_1)); - ProcessMarkStack(threadId); -} - -void NonMovableMarker::ProcessMarkStack(uint32_t threadId) -{ - WorkerHelper *worklist = heap_->GetWorkList(); - TaggedObject *obj = nullptr; - bool isOnlySemi = heap_->IsSemiMarkNeeded(); - while (true) { - obj = nullptr; - if (!worklist->Pop(threadId, &obj)) { - break; - } - - JSHClass *jsHclass = obj->GetClass(); - MarkObject(threadId, jsHclass); - - Region *objectRegion = Region::ObjectAddressToRange(obj); - bool needBarrier = !isOnlySemi && !objectRegion->InYoungAndCSetGeneration(); - objXRay_.VisitObjectBody(obj, jsHclass, - std::bind(&Marker::HandleObjectVisitor, this, threadId, objectRegion, - needBarrier, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - } -} - -void SemiGcMarker::Initialized() -{ - ageMark_ = heap_->GetNewSpace()->GetAgeMark(); -} - -void SemiGcMarker::ProcessMarkStack(uint32_t threadId) -{ - WorkerHelper *worklist = heap_->GetWorkList(); - TaggedObject *obj = nullptr; - while (true) { - obj = nullptr; - if (!worklist->Pop(threadId, &obj)) { - break; - } - - auto jsHclass = obj->GetClass(); - Region *objectRegion = Region::ObjectAddressToRange(obj); - bool promoted = !objectRegion->InYoungGeneration(); - objXRay_.VisitObjectBody(obj, jsHclass, - std::bind(&Marker::HandleMoveObjectVisitor, this, threadId, promoted, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - } -} - -void CompressGcMarker::ProcessMarkStack(uint32_t threadId) -{ - WorkerHelper *worklist = heap_->GetWorkList(); - TaggedObject *obj = nullptr; - while (true) { - obj = nullptr; - if (!worklist->Pop(threadId, &obj)) { - break; - } - - auto jsHclass = obj->GetClass(); - ObjectSlot objectSlot(ToUintPtr(obj)); - MarkObject(threadId, jsHclass, objectSlot); - - objXRay_.VisitObjectBody(obj, jsHclass, - std::bind(&Marker::HandleMoveObjectVisitor, this, threadId, false, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - } -} -} // namespace panda::ecmascript -#endif // __clang_analyzer__ diff --git a/runtime/mem/parallel_marker.h b/runtime/mem/parallel_marker.h deleted file mode 100644 index f01b9730cb2a2ddc2c89e1f3b2f5b16db9d5452f..0000000000000000000000000000000000000000 --- a/runtime/mem/parallel_marker.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_PARALLEL_MARKER_H -#define ECMASCRIPT_MEM_PARALLEL_MARKER_H - -#include "plugins/ecmascript/runtime/js_hclass.h" -#include "plugins/ecmascript/runtime/mem/object_xray.h" -#include "plugins/ecmascript/runtime/mem/remembered_set.h" -#include "plugins/ecmascript/runtime/mem/slots.h" -#include "libpandabase/utils/logger.h" - -namespace panda::ecmascript { -class Heap; -class TaggedObject; -class Region; - -class Marker { -public: - explicit Marker(Heap *heap); - virtual ~Marker() = default; - - virtual void Initialized() - { - ECMA_GC_LOG() << "Marker::Initialize do nothing"; - } - - void MarkRoots(uint32_t threadId); - void ProcessOldToNew(uint32_t threadId); // for HPPGC only semi mode - void ProcessOldToNew(uint32_t threadId, Region *region); // for SemiGC - void ProcessSnapshotRSet(uint32_t threadId); // for SemiGC - - virtual void ProcessMarkStack([[maybe_unused]] uint32_t threadId) - { - LOG(FATAL, ECMASCRIPT) << "can not call this method"; - } - - inline void HandleObjectVisitor(uint32_t threadId, Region *objectRegion, bool needBarrier, - [[maybe_unused]] TaggedObject *root, ObjectSlot start, ObjectSlot end); - inline void HandleMoveObjectVisitor(uint32_t threadId, bool promoted, TaggedObject *root, ObjectSlot start, - ObjectSlot end); - - NO_COPY_SEMANTIC(Marker); - NO_MOVE_SEMANTIC(Marker); - -protected: - virtual inline void MarkObject([[maybe_unused]] uint32_t threadId, - [[maybe_unused]] TaggedObject *object) // non move - { - LOG(FATAL, ECMASCRIPT) << "can not call this method"; - } - - virtual inline SlotStatus MarkObject([[maybe_unused]] uint32_t threadId, [[maybe_unused]] TaggedObject *object, - [[maybe_unused]] ObjectSlot slot) // move - { - LOG(FATAL, ECMASCRIPT) << "can not call this method"; - return SlotStatus::KEEP_SLOT; - } - - virtual void HandleOldToNewRSet(uint32_t threadId, Region *region) = 0; - virtual void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) = 0; - virtual void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, ObjectSlot end) = 0; - virtual inline void RecordWeakReference([[maybe_unused]] uint32_t threadId, [[maybe_unused]] JSTaggedType *ref) - { - LOG(FATAL, ECMASCRIPT) << "can not call this method"; - } - - Heap *heap_; // NOLINT(misc-non-private-member-variables-in-classes) - ObjectXRay objXRay_; // NOLINT(misc-non-private-member-variables-in-classes) -}; - -class NonMovableMarker : public Marker { -public: - explicit NonMovableMarker(Heap *heap) : Marker(heap) {} - -protected: - void ProcessMarkStack(uint32_t threadId) override; - void MarkObject(uint32_t threadId, TaggedObject *object) override; - void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) override; - void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, ObjectSlot end) override; - - void HandleOldToNewRSet(uint32_t threadId, Region *region) override; - void RecordWeakReference(uint32_t threadId, JSTaggedType *ref) override; -}; - -class MovableMarker : public Marker { -public: - explicit MovableMarker(Heap *heap) : Marker(heap) {} - -protected: - void HandleRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot slot) override; - void HandleRangeRoots(uint32_t threadId, [[maybe_unused]] Root type, ObjectSlot start, ObjectSlot end) override; - virtual inline SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, - ObjectSlot slot) = 0; - - void HandleOldToNewRSet(uint32_t threadId, Region *region) override; - - inline uintptr_t AllocateDstSpace(uint32_t threadId, size_t size, bool &shouldPromote); - inline void UpdateForwardAddressIfSuccess(uint32_t threadId, TaggedObject *object, JSHClass *klass, - uintptr_t toAddress, size_t size, const MarkWord &markWord, - ObjectSlot slot); - inline bool UpdateForwardAddressIfFailed(TaggedObject *object, uintptr_t toAddress, size_t size, ObjectSlot slot); - inline void CopyObjectWithoutHeader(TaggedObject *object, uintptr_t toAddress, size_t size); -}; - -class SemiGcMarker : public MovableMarker { -public: - explicit SemiGcMarker(Heap *heap) : MovableMarker(heap) {} - - void Initialized() override; - -protected: - void ProcessMarkStack(uint32_t threadId) override; - SlotStatus MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot slot) override; - SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, - ObjectSlot slot) override; - void RecordWeakReference(uint32_t threadId, JSTaggedType *ref) override; - -private: - inline bool ShouldBePromoted(TaggedObject *object); - - uintptr_t ageMark_ {0}; -}; - -class CompressGcMarker : public MovableMarker { -public: - explicit CompressGcMarker(Heap *heap) : MovableMarker(heap) {} - -protected: - void ProcessMarkStack(uint32_t threadId) override; - SlotStatus MarkObject(uint32_t threadId, TaggedObject *object, ObjectSlot slot) override; - - SlotStatus EvacuateObject(uint32_t threadId, TaggedObject *object, const MarkWord &markWord, - ObjectSlot slot) override; - void RecordWeakReference(uint32_t threadId, JSTaggedType *ref) override; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_PARALLEL_MARKER_H diff --git a/runtime/mem/parallel_work_helper.cpp b/runtime/mem/parallel_work_helper.cpp deleted file mode 100644 index 7628f581c82f7ea970f056cb377a7d84bb2ccddc..0000000000000000000000000000000000000000 --- a/runtime/mem/parallel_work_helper.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/parallel_work_helper.h" - -#include "plugins/ecmascript/runtime/js_hclass-inl.h" -#include "plugins/ecmascript/runtime/mem/area.h" -#include "plugins/ecmascript/runtime/mem/compress_collector.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/mark_stack.h" -#include "plugins/ecmascript/runtime/mem/mix_space_collector.h" -#include "plugins/ecmascript/runtime/mem/region.h" -#include "plugins/ecmascript/runtime/mem/region_factory.h" -#include "plugins/ecmascript/runtime/mem/tlab_allocator-inl.h" - -namespace panda::ecmascript { -WorkerHelper::WorkerHelper(Heap *heap, uint32_t threadNum) - : heap_(heap), threadNum_(threadNum), markSpace_(0), spaceTop_(0), markSpaceEnd_(0) -{ - for (uint32_t i = 0; i < threadNum_; i++) { - continuousQueue_[i] = new ProcessQueue(heap); - } - markSpace_ = ToUintPtr(const_cast(heap_->GetRegionFactory())->AllocateBuffer(SPACE_SIZE)); -} - -WorkerHelper::~WorkerHelper() -{ - for (uint32_t i = 0; i < threadNum_; i++) { - continuousQueue_[i]->Destroy(); - delete continuousQueue_[i]; - continuousQueue_[i] = nullptr; - } - const_cast(heap_->GetRegionFactory())->FreeBuffer(reinterpret_cast(markSpace_)); -} - -bool WorkerHelper::Push(uint32_t threadId, TaggedObject *object) -{ - WorkNode *&pushNode = workList_[threadId].pushNode_; - if (!pushNode->Push(ToUintPtr(object))) { - PushWorkNodeToGlobal(threadId); - return pushNode->Push(ToUintPtr(object)); - } - return true; -} - -bool WorkerHelper::Push(uint32_t threadId, TaggedObject *object, Region *region) -{ - if (Push(threadId, object)) { - auto klass = object->GetClass(); - auto size = klass->SizeFromJSHClass(object); - region->IncrementAliveObject(size); - return true; - } - return false; -} - -void WorkerHelper::PushWorkNodeToGlobal(uint32_t threadId, bool postTask) -{ - WorkNode *&pushNode = workList_[threadId].pushNode_; - if (!pushNode->IsEmpty()) { - globalWork_.Push(pushNode); - pushNode = AllocalWorkNode(); - if (postTask && heap_->IsParallelGCEnabled() && heap_->CheckCanDistributeTask()) { - heap_->PostParallelGCTask(parallelTask_); - } - } -} - -bool WorkerHelper::Pop(uint32_t threadId, TaggedObject **object) -{ - WorkNode *&popNode = workList_[threadId].popNode_; - WorkNode *&pushNode = workList_[threadId].pushNode_; - if (!popNode->Pop(reinterpret_cast(object))) { - if (!pushNode->IsEmpty()) { - WorkNode *tmp = popNode; - popNode = pushNode; - pushNode = tmp; - } else if (!PopWorkNodeFromGlobal(threadId)) { - return false; - } - return popNode->Pop(reinterpret_cast(object)); - } - return true; -} - -bool WorkerHelper::PopWorkNodeFromGlobal(uint32_t threadId) -{ - return globalWork_.Pop(&workList_[threadId].popNode_); -} - -void WorkerHelper::Finish(size_t &aliveSize) -{ - for (uint32_t i = 0; i < threadNum_; i++) { - WorkNodeHolder &holder = workList_[i]; - holder.weakQueue_->FinishMarking(continuousQueue_[i]); - delete holder.weakQueue_; - holder.weakQueue_ = nullptr; - delete holder.allocator_; - holder.allocator_ = nullptr; - holder.waitUpdate_.clear(); - aliveSize += holder.aliveSize_; - } - - while (!unuseSpace_.empty()) { - const_cast(heap_->GetRegionFactory()) - ->FreeBuffer(reinterpret_cast(unuseSpace_.back())); - unuseSpace_.pop_back(); - } -} - -void WorkerHelper::Finish(size_t &aliveSize, size_t &promoteSize) -{ - Finish(aliveSize); - for (uint32_t i = 0; i < threadNum_; i++) { - WorkNodeHolder &holder = workList_[i]; - promoteSize += holder.aliveSize_; - } -} - -void WorkerHelper::Initialize(TriggerGCType gcType, ParallelGCTaskPhase parallelTask) -{ - parallelTask_ = parallelTask; - spaceTop_ = markSpace_; - markSpaceEnd_ = markSpace_ + SPACE_SIZE; - for (uint32_t i = 0; i < threadNum_; i++) { - WorkNodeHolder &holder = workList_[i]; - holder.pushNode_ = AllocalWorkNode(); - holder.popNode_ = AllocalWorkNode(); - holder.weakQueue_ = new ProcessQueue(); - holder.weakQueue_->BeginMarking(heap_, continuousQueue_[i]); - holder.aliveSize_ = 0; - holder.promoteSize_ = 0; - if (gcType == TriggerGCType::SEMI_GC) { - holder.allocator_ = new TlabAllocator(heap_, TriggerGCType::SEMI_GC); - } else if (gcType == TriggerGCType::COMPRESS_FULL_GC) { - holder.allocator_ = new TlabAllocator(heap_, TriggerGCType::COMPRESS_FULL_GC); - } - } -} - -WorkNode *WorkerHelper::AllocalWorkNode() -{ - size_t totalSize = sizeof(WorkNode) + sizeof(Stack) + STACK_AREA_SIZE; - // CAS - volatile auto atomicField = reinterpret_cast *>(&spaceTop_); - bool result = false; - uintptr_t begin = 0; - do { - begin = atomicField->load(std::memory_order_acquire); - if (begin + totalSize >= markSpaceEnd_) { - os::memory::LockHolder lock(mtx_); - begin = atomicField->load(std::memory_order_acquire); - if (begin + totalSize >= markSpaceEnd_) { - unuseSpace_.emplace_back(markSpace_); - markSpace_ = - ToUintPtr(const_cast(heap_->GetRegionFactory())->AllocateBuffer(SPACE_SIZE)); - spaceTop_ = markSpace_; - markSpaceEnd_ = markSpace_ + SPACE_SIZE; - begin = spaceTop_; - } - } - result = std::atomic_compare_exchange_strong_explicit(atomicField, &begin, begin + totalSize, - std::memory_order_release, std::memory_order_relaxed); - } while (!result); - auto *stack = reinterpret_cast(begin + sizeof(WorkNode)); - stack->ResetBegin(begin + sizeof(WorkNode) + sizeof(Stack), begin + totalSize); - auto *work = reinterpret_cast(begin); - return new (work) WorkNode(stack); -} -} // namespace panda::ecmascript diff --git a/runtime/mem/parallel_work_helper.h b/runtime/mem/parallel_work_helper.h deleted file mode 100644 index f68542137549b125c2362851b4ca2e807fcfa07e..0000000000000000000000000000000000000000 --- a/runtime/mem/parallel_work_helper.h +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_PARALLEL_WORK_HELPER_H -#define ECMASCRIPT_MEM_PARALLEL_WORK_HELPER_H - -#include "plugins/ecmascript/runtime/mem/mark_stack-inl.h" -#include "plugins/ecmascript/runtime/mem/slots.h" -#include "plugins/ecmascript/runtime/platform/platform.h" - -namespace panda::ecmascript { -using SlotNeedUpdate = std::pair; - -static constexpr uint32_t MARKSTACK_MAX_SIZE = 100; -static constexpr uint32_t STACK_AREA_SIZE = sizeof(uintptr_t) * MARKSTACK_MAX_SIZE; -static constexpr uint32_t SPACE_SIZE = 8 * 1024; - -class Heap; -class Stack; -class SemiSpaceCollector; -class TlabAllocator; -class Region; - -enum ParallelGCTaskPhase { - SEMI_HANDLE_THREAD_ROOTS_TASK, - SEMI_HANDLE_SNAPSHOT_TASK, - SEMI_HANDLE_GLOBAL_POOL_TASK, - OLD_HANDLE_GLOBAL_POOL_TASK, - COMPRESS_HANDLE_GLOBAL_POOL_TASK, - CONCURRENT_HANDLE_GLOBAL_POOL_TASK, - CONCURRENT_HANDLE_OLD_TO_NEW_TASK, - TASK_LAST // Count of different Task phase -}; - -class WorkNode { -public: - explicit WorkNode(Stack *stack) : stack_(stack) {} - ~WorkNode() - { - delete stack_; - stack_ = nullptr; - } - - NO_COPY_SEMANTIC(WorkNode); - NO_MOVE_SEMANTIC(WorkNode); - - bool Push(uintptr_t obj) - { - return stack_->PushBackChecked(obj); - } - - bool Pop(uintptr_t *obj) - { - if (IsEmpty()) { - return false; - } - auto object = ToVoidPtr(*obj); - if (object != nullptr) { - delete reinterpret_cast(object); - } - *obj = stack_->PopBackUnchecked(); - return true; - } - - bool IsEmpty() const - { - return stack_->IsEmpty(); - } - - WorkNode *Next() const - { - return next_; - } - - void SetNext(WorkNode *node) - { - next_ = node; - } - -private: - WorkNode *next_ {nullptr}; - Stack *stack_; -}; - -class GlobalWorkList { -public: - GlobalWorkList() = default; - ~GlobalWorkList() = default; - - NO_COPY_SEMANTIC(GlobalWorkList); - NO_MOVE_SEMANTIC(GlobalWorkList); - - void Push(WorkNode *node) - { - if (node == nullptr) { - return; - } - os::memory::LockHolder lock(mtx_); - node->SetNext(top_); - top_ = node; - } - - bool Pop(WorkNode **node) - { - os::memory::LockHolder lock(mtx_); - if (top_ == nullptr) { - return false; - } - *node = top_; - top_ = top_->Next(); - return true; - } - -private: - WorkNode *top_ {nullptr}; - os::memory::Mutex mtx_; -}; - -struct WorkNodeHolder { - WorkNode *pushNode_ {nullptr}; - WorkNode *popNode_ {nullptr}; - ProcessQueue *weakQueue_ {nullptr}; - std::vector waitUpdate_; - TlabAllocator *allocator_ {nullptr}; - size_t aliveSize_ = 0; - size_t promoteSize_ = 0; -}; - -class WorkerHelper final { -public: - WorkerHelper() = delete; - explicit WorkerHelper(Heap *heap, uint32_t threadNum); - ~WorkerHelper(); - - void Initialize(TriggerGCType gcType, ParallelGCTaskPhase parallelTask); - void Finish(size_t &aliveSize); - void Finish(size_t &aliveSize, size_t &promoteSize); - - bool Push(uint32_t threadId, TaggedObject *object); - bool Push(uint32_t threadId, TaggedObject *object, Region *region); - bool Pop(uint32_t threadId, TaggedObject **object); - - bool PopWorkNodeFromGlobal(uint32_t threadId); - void PushWorkNodeToGlobal(uint32_t threadId, bool postTask = true); - - inline void PushWeakReference(uint32_t threadId, JSTaggedType *weak) - { - workList_[threadId].weakQueue_->PushBack(weak); - } - - inline void AddAliveSize(uint32_t threadId, size_t size) - { - workList_[threadId].aliveSize_ += size; - } - - inline void AddPromoteSize(uint32_t threadId, size_t size) - { - workList_[threadId].promoteSize_ += size; - } - - inline ProcessQueue *GetWeakReferenceQueue(uint32_t threadId) const - { - return workList_[threadId].weakQueue_; - } - - inline TlabAllocator *GetTlabAllocator(uint32_t threadId) const - { - return workList_[threadId].allocator_; - } - - inline void PushWaitUpdateSlot(uint32_t threadId, SlotNeedUpdate slot) - { - workList_[threadId].waitUpdate_.emplace_back(slot); - } - - inline bool GetSlotNeedUpdate(uint32_t threadId, SlotNeedUpdate *slot) - { - std::vector &waitUpdate = workList_[threadId].waitUpdate_; - if (waitUpdate.empty()) { - return false; - } - *slot = waitUpdate.back(); - waitUpdate.pop_back(); - return true; - } - -private: - NO_COPY_SEMANTIC(WorkerHelper); - NO_MOVE_SEMANTIC(WorkerHelper); - - WorkNode *AllocalWorkNode(); - - Heap *heap_; - uint32_t threadNum_; - std::array workList_; - std::array *, MAX_PLATFORM_THREAD_NUM + 1> continuousQueue_ {}; - GlobalWorkList globalWork_; - uintptr_t markSpace_; - uintptr_t spaceTop_; - uintptr_t markSpaceEnd_; - std::vector unuseSpace_; - os::memory::Mutex mtx_; - ParallelGCTaskPhase parallelTask_ {}; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_PARALLEL_WORK_HELPER_H diff --git a/runtime/mem/region-inl.h b/runtime/mem/region-inl.h deleted file mode 100644 index cdcbca401af035a4454cfeca96cff444d5edab01..0000000000000000000000000000000000000000 --- a/runtime/mem/region-inl.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_REGION_INL_H -#define ECMASCRIPT_MEM_REGION_INL_H - -#include "plugins/ecmascript/runtime/mem/region.h" - -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/region_factory.h" -#include "plugins/ecmascript/runtime/mem/remembered_set.h" -#include "plugins/ecmascript/runtime/mem/space.h" - -namespace panda::ecmascript { -inline void Region::SetSpace(Space *space) -{ - space_ = space; - heap_ = space_->GetHeap(); -} - -inline RangeBitmap *Region::GetOrCreateMarkBitmap() -{ - if (UNLIKELY(markBitmap_ == nullptr)) { - os::memory::LockHolder lock(lock_); - if (markBitmap_ == nullptr) { - markBitmap_ = CreateMarkBitmap(); - } - } - return markBitmap_; -} - -RangeBitmap *Region::CreateMarkBitmap() -{ - size_t heapSize = IsFlagSet(RegionFlags::IS_HUGE_OBJECT) ? LARGE_BITMAP_MIN_SIZE : GetCapacity(); - // Only one huge object is stored in a region. The BitmapSize of a huge region will always be 8 Bytes. - size_t bitmapSize = RangeBitmap::GetBitMapSizeInByte(heapSize); - - auto bitmapData = const_cast(heap_->GetRegionFactory())->Allocate(bitmapSize); - auto *ret = new RangeBitmap(this, heapSize, bitmapData); - - ret->ClearAllBits(); - return ret; -} - -RememberedSet *Region::CreateRememberedSet() -{ - auto setSize = RememberedSet::GetSizeInByte(GetCapacity()); - auto setAddr = const_cast(heap_->GetRegionFactory())->Allocate(setSize); - uintptr_t setData = ToUintPtr(setAddr); - auto ret = new RememberedSet(ToUintPtr(this), GetCapacity(), setData); - ret->ClearAllBits(); - return ret; -} - -RememberedSet *Region::GetOrCreateCrossRegionRememberedSet() -{ - if (UNLIKELY(crossRegionSet_ == nullptr)) { - os::memory::LockHolder lock(lock_); - if (crossRegionSet_ == nullptr) { - crossRegionSet_ = CreateRememberedSet(); - } - } - return crossRegionSet_; -} - -RememberedSet *Region::GetOrCreateOldToNewRememberedSet() -{ - if (UNLIKELY(oldToNewSet_ == nullptr)) { - os::memory::LockHolder lock(lock_); - if (oldToNewSet_ == nullptr) { - oldToNewSet_ = CreateRememberedSet(); - } - } - return oldToNewSet_; -} - -void Region::InsertCrossRegionRememberedSet(uintptr_t addr) -{ - auto set = GetOrCreateCrossRegionRememberedSet(); - set->Insert(addr); -} - -void Region::AtomicInsertCrossRegionRememberedSet(uintptr_t addr) -{ - auto set = GetOrCreateCrossRegionRememberedSet(); - set->AtomicInsert(addr); -} - -void Region::InsertOldToNewRememberedSet(uintptr_t addr) -{ - auto set = GetOrCreateOldToNewRememberedSet(); - set->Insert(addr); -} - -WorkerHelper *Region::GetWorkList() const -{ - return heap_->GetWorkList(); -} - -void Region::AtomicInsertOldToNewRememberedSet(uintptr_t addr) -{ - auto set = GetOrCreateOldToNewRememberedSet(); - set->AtomicInsert(addr); -} - -void Region::ClearMarkBitmap() -{ - if (markBitmap_ != nullptr) { - auto size = RangeBitmap::GetBitMapSizeInByte(GetCapacity()); - const_cast(heap_->GetRegionFactory())->Free(markBitmap_->GetBitMap().Data(), size); - delete markBitmap_; - markBitmap_ = nullptr; - } -} - -void Region::ClearCrossRegionRememberedSet() -{ - if (crossRegionSet_ != nullptr) { - auto size = RememberedSet::GetSizeInByte(GetCapacity()); - const_cast(heap_->GetRegionFactory())->Free(crossRegionSet_->GetBitMap().Data(), size); - delete crossRegionSet_; - crossRegionSet_ = nullptr; - } -} - -void Region::ClearOldToNewRememberedSet() -{ - if (oldToNewSet_ != nullptr) { - auto size = RememberedSet::GetSizeInByte(GetCapacity()); - const_cast(heap_->GetRegionFactory())->Free(oldToNewSet_->GetBitMap().Data(), size); - delete oldToNewSet_; - oldToNewSet_ = nullptr; - } -} -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_REGION_INL_H diff --git a/runtime/mem/region.h b/runtime/mem/region.h deleted file mode 100644 index fe956eeddc7e0ac2d346d7b8fef1e6447afee995..0000000000000000000000000000000000000000 --- a/runtime/mem/region.h +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_REGION_H -#define ECMASCRIPT_MEM_REGION_H - -#include "plugins/ecmascript/runtime/mem/free_object_list.h" -#include "plugins/ecmascript/runtime/mem/mem.h" -#include "mem/gc/bitmap.h" - -namespace panda { -using RangeBitmap = mem::MemBitmap(ecmascript::MemAlignment::MEM_ALIGN_OBJECT)>; - -namespace ecmascript { -class Space; -class Heap; -class RememberedSet; -class WorkerHelper; - -enum RegionFlags : uint32_t { - NEVER_EVACUATE = 1, - HAS_AGE_MARK = 1 << 1, // NOLINT(hicpp-signed-bitwise) - BELOW_AGE_MARK = 1 << 2, // NOLINT(hicpp-signed-bitwise) - IS_IN_YOUNG_GENERATION = 1 << 3, // NOLINT(hicpp-signed-bitwise) - IS_IN_SNAPSHOT_GENERATION = 1 << 4, // NOLINT(hicpp-signed-bitwise) - IS_HUGE_OBJECT = 1 << 5, // NOLINT(hicpp-signed-bitwise) - IS_IN_OLD_GENERATION = 1 << 6, // NOLINT(hicpp-signed-bitwise) - IS_IN_NON_MOVABLE_GENERATION = 1 << 7, // NOLINT(hicpp-signed-bitwise) - IS_IN_YOUNG_OR_OLD_GENERATION = IS_IN_YOUNG_GENERATION | IS_IN_OLD_GENERATION, - IS_IN_COLLECT_SET = 1 << 8, // NOLINT(hicpp-signed-bitwise) - IS_IN_PROMOTE_SET = 1 << 9, // NOLINT(hicpp-signed-bitwise) - IS_IN_YOUNG_OR_CSET_GENERATION = IS_IN_YOUNG_GENERATION | IS_IN_COLLECT_SET, - IS_INVALID = 1 << 10, // NOLINT(hicpp-signed-bitwise) -}; - -class Region { -public: - Region(Space *space, Heap *heap, uintptr_t allocateBase, uintptr_t begin, uintptr_t end) - : space_(space), - heap_(heap), - allocateBase_(allocateBase), - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - begin_(begin), - end_(end), - highWaterMark_(end), - aliveObject_(0) - { - } - ~Region() = default; - NO_COPY_SEMANTIC(Region); - NO_MOVE_SEMANTIC(Region); - - void Reset() - { - flags_ = 0; - highWaterMark_ = end_; - memset_s(reinterpret_cast(begin_), GetSize(), 0, GetSize()); - } - - void LinkNext(Region *next) - { - next_ = next; - } - - Region *GetNext() const - { - return next_; - } - - void LinkPrev(Region *prev) - { - prev_ = prev; - } - - Region *GetPrev() const - { - return prev_; - } - - uintptr_t GetBegin() const - { - return begin_; - } - - uintptr_t GetEnd() const - { - return end_; - } - - size_t GetCapacity() const - { - return end_ - reinterpret_cast(this); - } - - size_t GetSize() const - { - return end_ - begin_; - } - - inline void SetSpace(Space *space); - - Heap *GetHeap() const - { - return heap_; - } - - void ResetFlag() - { - flags_ = 0; - } - - void SetFlag(RegionFlags flag) - { - flags_ |= flag; - } - - void ClearFlag(RegionFlags flag) - { - // NOLINTNEXTLINE(hicpp-signed-bitwise) - flags_ &= ~flag; - } - - bool IsFlagSet(RegionFlags flag) const - { - return (flags_ & flag) != 0; - } - - RangeBitmap *GetMarkBitmap() - { - return markBitmap_; - } - - RememberedSet *GetCrossRegionRememberedSet() - { - return crossRegionSet_; - } - - RememberedSet *GetOldToNewRememberedSet() - { - return oldToNewSet_; - } - - static Region *ObjectAddressToRange(TaggedObject *obj) - { - return reinterpret_cast(ToUintPtr(obj) & ~DEFAULT_REGION_MASK); - } - - static Region *ObjectAddressToRange(uintptr_t objAddress) - { - return reinterpret_cast(objAddress & ~DEFAULT_REGION_MASK); - } - - bool InYoungGeneration() const - { - return IsFlagSet(RegionFlags::IS_IN_YOUNG_GENERATION); - } - - bool InOldGeneration() const - { - return IsFlagSet(RegionFlags::IS_IN_OLD_GENERATION); - } - - bool InYoungAndOldGeneration() const - { - return IsFlagSet(RegionFlags::IS_IN_YOUNG_OR_OLD_GENERATION); - } - - bool InYoungAndCSetGeneration() const - { - return IsFlagSet(RegionFlags::IS_IN_YOUNG_OR_CSET_GENERATION); - } - - bool InPromoteSet() const - { - return IsFlagSet(RegionFlags::IS_IN_PROMOTE_SET); - } - - bool InCollectSet() const - { - return IsFlagSet(RegionFlags::IS_IN_COLLECT_SET); - } - - bool HasAgeMark() const - { - return IsFlagSet(RegionFlags::HAS_AGE_MARK); - } - - bool BelowAgeMark() const - { - return IsFlagSet(RegionFlags::BELOW_AGE_MARK); - } - - bool InRange(uintptr_t address) - { - return address >= begin_ && address <= end_; - } - - inline RangeBitmap *GetOrCreateMarkBitmap(); - inline RangeBitmap *CreateMarkBitmap(); - inline void ClearMarkBitmap(); - inline RememberedSet *CreateRememberedSet(); - inline RememberedSet *GetOrCreateCrossRegionRememberedSet(); - inline RememberedSet *GetOrCreateOldToNewRememberedSet(); - inline void InsertCrossRegionRememberedSet(uintptr_t addr); - inline void AtomicInsertCrossRegionRememberedSet(uintptr_t addr); - inline void InsertOldToNewRememberedSet(uintptr_t addr); - inline void AtomicInsertOldToNewRememberedSet(uintptr_t addr); - inline void ClearCrossRegionRememberedSet(); - inline void ClearOldToNewRememberedSet(); - - uintptr_t GetAllocateBase() const - { - return allocateBase_; - } - - size_t GetAllocatedBytes(uintptr_t top = 0) - { - ASSERT(top == 0 || InRange(top)); - return (top == 0) ? (highWaterMark_ - begin_) : (top - begin_); - } - - void SetHighWaterMark(uintptr_t mark) - { - ASSERT(InRange(mark)); - highWaterMark_ = mark; - } - - int SetCodeExecutableAndReadable() - { - // NOLINTNEXTLINE(hicpp-signed-bitwise) - int res = mprotect(reinterpret_cast(allocateBase_), GetCapacity(), PROT_EXEC | PROT_READ | PROT_WRITE); - return res; - } - - void InitializeKind() - { - kinds_ = Span(new FreeObjectKind *[FreeObjectList::NumberOfKinds()](), - FreeObjectList::NumberOfKinds()); - } - - void RebuildKind() - { - EnumerateKinds([](FreeObjectKind *kind) { - if (kind != nullptr) { - kind->Rebuild(); - } - }); - } - - void DestroyKind() - { - for (auto kind : kinds_) { - delete kind; - } - delete[] kinds_.data(); - } - - FreeObjectKind *GetFreeObjectKind(KindType type) - { - // Thread safe - if (kinds_[type] == nullptr) { - kinds_[type] = new FreeObjectKind(type); - } - return kinds_[type]; - } - - template - void EnumerateKinds(Callback cb) - { - for (auto kind : kinds_) { - cb(kind); - } - } - - bool IsMarking() const - { - return marking_; - } - - void SetMarking(bool isMarking) - { - marking_ = isMarking; - } - - inline WorkerHelper *GetWorkList() const; - - void IncrementAliveObject(size_t size) - { - aliveObject_ += size; - } - - void DecreaseAliveObject(size_t size) - { - aliveObject_ -= size; - } - - void SetAliveObject(size_t size) - { - aliveObject_ = size; - } - - void ResetAliveObject() - { - aliveObject_ = 0; - } - - size_t AliveObject() const - { - return aliveObject_; - } - - bool MostObjectAlive() const - { - return aliveObject_ > MOST_OBJECT_ALIVE_THRESHOLD_PERCENT * GetSize(); - } - -private: - static constexpr double MOST_OBJECT_ALIVE_THRESHOLD_PERCENT = 0.8; - Space *space_; - Heap *heap_; - uintptr_t flags_ {0}; // Memory alignment, only low 32bits are used now - uintptr_t allocateBase_; - uintptr_t begin_; - uintptr_t end_; - uintptr_t highWaterMark_; - bool marking_ {false}; - std::atomic_size_t aliveObject_ {0}; - Region *next_ {nullptr}; - Region *prev_ {nullptr}; - RangeBitmap *markBitmap_ {nullptr}; - RememberedSet *crossRegionSet_ {nullptr}; - RememberedSet *oldToNewSet_ {nullptr}; - Span kinds_; - os::memory::Mutex lock_; - friend class SnapShot; -}; -} // namespace ecmascript -} // namespace panda - -#endif // ECMASCRIPT_MEM_REGION_H diff --git a/runtime/mem/region_factory.cpp b/runtime/mem/region_factory.cpp deleted file mode 100644 index d5ceff43f6eb34da97cf11fda4de871a140ac791..0000000000000000000000000000000000000000 --- a/runtime/mem/region_factory.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MM_REGION_FACTORY_H -#define ECMASCRIPT_MM_REGION_FACTORY_H - -#include "plugins/ecmascript/runtime/mem/region_factory.h" - -#include - -#include "plugins/ecmascript/runtime/mem/mark_stack.h" -#include "plugins/ecmascript/runtime/mem/region.h" -#include "libpandabase/mem/pool_manager.h" -#include "os/mem.h" - -namespace panda::ecmascript { -Region *RegionFactory::AllocateAlignedRegion(Space *space, size_t capacity) -{ - if (capacity == 0) { - LOG_ECMA_MEM(FATAL) << "capacity must have a size bigger than 0"; - UNREACHABLE(); - } - size_t commitSize = capacity; - - auto pool = PoolManager::GetMmapMemPool()->AllocPool(commitSize, panda::SpaceType::SPACE_TYPE_OBJECT, - AllocatorType::RUNSLOTS_ALLOCATOR, nullptr); - void *mapMem = pool.GetMem(); -#if ECMASCRIPT_ENABLE_ZAP_MEM - memset_s(mapMem, commitSize, 0, commitSize); -#endif - if (mapMem == nullptr) { - LOG_ECMA_MEM(FATAL) << "pool is empty " << annoMemoryUsage_.load(std::memory_order_relaxed); - UNREACHABLE(); - } - IncreaseAnnoMemoryUsage(capacity); - - uintptr_t mem = ToUintPtr(mapMem); - // Check that the address is 256K byte aligned - LOG_IF(AlignUp(mem, PANDA_POOL_ALIGNMENT_IN_BYTES) != mem, FATAL, RUNTIME) << "region not align by 256KB"; - - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - uintptr_t begin = AlignUp(mem + sizeof(Region), static_cast(MemAlignment::MEM_ALIGN_REGION)); - uintptr_t end = mem + capacity; - - return new (ToVoidPtr(mem)) Region(space, space->GetHeap(), mem, begin, end); -} - -void RegionFactory::FreeRegion(Region *region) -{ - auto size = region->GetCapacity(); - DecreaseAnnoMemoryUsage(size); -#if ECMASCRIPT_ENABLE_ZAP_MEM - memset_s(ToVoidPtr(region->GetAllocateBase()), size, INVALID_VALUE, size); -#endif - PoolManager::GetMmapMemPool()->FreePool(ToVoidPtr(region->GetAllocateBase()), size); -} - -Area *RegionFactory::AllocateArea(size_t capacity) -{ - size_t headerSize = sizeof(Area); - if (capacity < headerSize) { - LOG_ECMA_MEM(FATAL) << "capacity must have a size not less than sizeof Area."; - UNREACHABLE(); - } - if (cachedArea_ != nullptr && capacity <= cachedArea_->GetSize()) { - auto result = cachedArea_; - cachedArea_ = nullptr; - return result; - } - // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) - void *mem = malloc(capacity); -#if ECMASCRIPT_ENABLE_ZAP_MEM - memset_s(mem, capacity, 0, capacity); -#endif - if (mem == nullptr) { - LOG_ECMA_MEM(FATAL) << "malloc failed"; - UNREACHABLE(); - } - IncreaseNativeMemoryUsage(capacity); - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - uintptr_t begin = reinterpret_cast(mem) + headerSize; - capacity -= headerSize; - return new (mem) Area(begin, capacity); -} - -void RegionFactory::FreeArea(Area *area) -{ - if (area == nullptr) { - return; - } - if (cachedArea_ == nullptr && area->GetSize() <= MAX_CACHED_CHUNK_AREA_SIZE) { - cachedArea_ = area; - return; - } - auto size = area->GetSize() + sizeof(Area); - DecreaseNativeMemoryUsage(size); -#if ECMASCRIPT_ENABLE_ZAP_MEM - memset_s(area, size, INVALID_VALUE, size); -#endif - // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) - free(reinterpret_cast(area)); -} - -void RegionFactory::Free(void *mem, size_t size) -{ - if (mem == nullptr) { - return; - } - DecreaseNativeMemoryUsage(size); -#if ECMASCRIPT_ENABLE_ZAP_MEM - memset_s(mem, size, INVALID_VALUE, size); -#endif - // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) - free(mem); -} - -void *RegionFactory::AllocateBuffer(size_t size) -{ - if (size == 0) { - LOG_ECMA_MEM(FATAL) << "size must have a size bigger than 0"; - UNREACHABLE(); - } - // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) - void *ptr = malloc(size); - if (ptr == nullptr) { - LOG_ECMA_MEM(FATAL) << "malloc failed"; - UNREACHABLE(); - } -#if ECMASCRIPT_ENABLE_ZAP_MEM - memset_s(ptr, size, INVALID_VALUE, size); -#endif - IncreaseNativeMemoryUsage(size); - return ptr; -} - -void RegionFactory::FreeBuffer(void *mem) -{ - if (mem == nullptr) { - return; - } - DecreaseNativeMemoryUsage(malloc_usable_size(mem)); -#if ECMASCRIPT_ENABLE_ZAP_MEM - memset_s(mem, size, INVALID_VALUE, size); -#endif - // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) - free(mem); -} - -void RegionFactory::FreeBufferFunc(void *buffer, void *data) -{ - if (buffer == nullptr || data == nullptr) { - return; - } - auto *factory = reinterpret_cast(data); - factory->FreeBuffer(buffer); -} -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MM_REGION_FACTORY_H diff --git a/runtime/mem/region_factory.h b/runtime/mem/region_factory.h deleted file mode 100644 index 2718197c4b26cbc754fbbcf0c7d7de62bc4cd106..0000000000000000000000000000000000000000 --- a/runtime/mem/region_factory.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_REGION_FACTORY_H -#define ECMASCRIPT_MEM_REGION_FACTORY_H - -#include - -#include "plugins/ecmascript/runtime/mem/mem.h" -#include "plugins/ecmascript/runtime/mem/area.h" -#include "libpandabase/utils/logger.h" - -namespace panda::ecmascript { -class Region; -class Space; -class Area; - -class RegionFactory { -public: - RegionFactory() = default; - virtual ~RegionFactory() - { - if (cachedArea_ != nullptr) { - FreeArea(cachedArea_); - cachedArea_ = nullptr; - } - } - - Region *AllocateAlignedRegion(Space *space, size_t capacity); - void FreeRegion(Region *region); - Area *AllocateArea(size_t capacity); - void FreeArea(Area *area); - void Free(void *mem, size_t size); - void *AllocateBuffer(size_t size); - void FreeBuffer(void *mem); - - static void FreeBufferFunc(void *buffer, void *data); - - // implemented by AllocateBuffer - template - std::enable_if_t, T *> New(Args &&...args) - { - void *p = AllocateBuffer(sizeof(T)); - if (UNLIKELY(p == nullptr)) { - return nullptr; - } - new (p) T(std::forward(args)...); // NOLINT(bugprone-throw-keyword-missing) - return reinterpret_cast(p); - } - - template - void Delete(T *ptr) - { - if (ptr == nullptr) { - return; - } - // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) - if constexpr (std::is_class_v) { - ptr->~T(); - } - FreeBuffer(ptr); - } - - void IncreaseAnnoMemoryUsage(size_t bytes) - { - size_t current = annoMemoryUsage_.fetch_add(bytes, std::memory_order_relaxed) + bytes; - size_t max = maxAnnoMemoryUsage_.load(std::memory_order_relaxed); - while (current > max && !maxAnnoMemoryUsage_.compare_exchange_weak(max, current, std::memory_order_relaxed)) { - } - } - - void DecreaseAnnoMemoryUsage(size_t bytes) - { - annoMemoryUsage_.fetch_sub(bytes, std::memory_order_relaxed); - } - - size_t GetAnnoMemoryUsage() const - { - return annoMemoryUsage_.load(std::memory_order_relaxed); - } - - size_t GetMaxAnnoMemoryUsage() const - { - return maxAnnoMemoryUsage_.load(std::memory_order_relaxed); - } - - void IncreaseNativeMemoryUsage(size_t bytes) - { - size_t current = nativeMemoryUsage_.fetch_add(bytes, std::memory_order_relaxed) + bytes; - size_t max = maxNativeMemoryUsage_.load(std::memory_order_relaxed); - while (current > max && !maxNativeMemoryUsage_.compare_exchange_weak(max, current, std::memory_order_relaxed)) { - } - } - - void DecreaseNativeMemoryUsage(size_t bytes) - { - nativeMemoryUsage_.fetch_sub(bytes, std::memory_order_relaxed); - } - - size_t GetNativeMemoryUsage() const - { - return nativeMemoryUsage_.load(std::memory_order_relaxed); - } - - size_t GetMaxNativeMemoryUsage() const - { - return maxNativeMemoryUsage_.load(std::memory_order_relaxed); - } - - void *Allocate(size_t size) - { - if (size == 0) { - LOG_ECMA_MEM(FATAL) << "size must have a size bigger than 0"; - UNREACHABLE(); - } - // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) - void *ptr = malloc(size); - if (ptr == nullptr) { - LOG_ECMA_MEM(FATAL) << "malloc failed"; - UNREACHABLE(); - } - IncreaseNativeMemoryUsage(size); - return ptr; - } - - static inline Area *AllocateSpace(size_t capacity) - { - size_t headerSize = sizeof(Area); - if (capacity < headerSize) { - LOG_ECMA_MEM(FATAL) << "capacity must have a size not less than sizeof Area."; - UNREACHABLE(); - } - // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) - void *mem = malloc(capacity); - if (mem == nullptr) { - LOG_ECMA_MEM(FATAL) << "malloc failed"; - UNREACHABLE(); - } - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - uintptr_t begin = reinterpret_cast(mem) + headerSize; - capacity -= headerSize; - return new (mem) Area(begin, capacity); - } - - static inline void FreeSpace(Area *area) - { - if (area == nullptr) { - return; - } - // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) - free(reinterpret_cast(area)); - } - -private: - NO_COPY_SEMANTIC(RegionFactory); - NO_MOVE_SEMANTIC(RegionFactory); - -#if ECMASCRIPT_ENABLE_ZAP_MEM - static constexpr int INVALID_VALUE = 0x7; -#endif - Area *cachedArea_ {nullptr}; - std::atomic annoMemoryUsage_ {0}; - std::atomic maxAnnoMemoryUsage_ {0}; - std::atomic nativeMemoryUsage_ {0}; - std::atomic maxNativeMemoryUsage_ {0}; -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_REGION_FACTORY_H diff --git a/runtime/mem/remembered_set.h b/runtime/mem/remembered_set.h deleted file mode 100644 index 81557527525f8699af4918c3c21230b2684be1d7..0000000000000000000000000000000000000000 --- a/runtime/mem/remembered_set.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_REMEMBERED_SET_H -#define ECMASCRIPT_MEM_REMEMBERED_SET_H - -#include "plugins/ecmascript/runtime/mem/mem.h" -#include "mem/gc/bitmap.h" - -namespace panda::ecmascript { -enum class SlotStatus : bool { - KEEP_SLOT, - CLEAR_SLOT, -}; - -class RememberedSet : public mem::Bitmap { -public: - using RememberedWordType = uintptr_t; - static const size_t BYTESPERCHUNK = static_cast(MemAlignment::MEM_ALIGN_OBJECT); - - RememberedSet(uintptr_t begin_addr, size_t range_size, uintptr_t bitset_addr) - : mem::Bitmap(reinterpret_cast(bitset_addr), range_size / BYTESPERCHUNK), - begin_addr_(begin_addr) - { - } - ~RememberedSet() = default; - NO_COPY_SEMANTIC(RememberedSet); - NO_MOVE_SEMANTIC(RememberedSet); - - void Insert(uintptr_t address) - { - SetBit(AddrToBitOffset(address)); - } - - void AtomicInsert(uintptr_t address) - { - AtomicTestAndSetBit(AddrToBitOffset(address)); - } - - template - void IterateOverSetBits(VisitorType visitor) - { - IterateOverSetBitsInRange(0, Size(), visitor); - } - - template - void IterateOverMarkedChunks(MemVisitor visitor) - { - IterateOverSetBits( - [&visitor, this](size_t bit_offset) -> bool { return visitor(BitOffsetToAddr(bit_offset)); }); - } - - void Clear(uintptr_t address) - { - ClearBit(AddrToBitOffset(address)); - } - - void ClearRange(uintptr_t begin, uintptr_t end) - { - ClearBitsInRange(AddrToBitOffset(begin), AddrToBitOffset(end)); - } - - static size_t GetSizeInByte(size_t range_size) - { - return (range_size >> mem::Bitmap::LOG_BITSPERWORD) / BYTESPERCHUNK * sizeof(mem::Bitmap::BitmapWordType); - } - -private: - void *BitOffsetToAddr(size_t bit_offset) const - { - return ToVoidPtr(begin_addr_ + bit_offset * BYTESPERCHUNK); - } - - size_t AddrToBitOffset(uintptr_t addr) const - { - return (addr - begin_addr_) / BYTESPERCHUNK; - } - - uintptr_t begin_addr_; -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_REMEMBERED_SET_H diff --git a/runtime/mem/semi_space_collector-inl.h b/runtime/mem/semi_space_collector-inl.h deleted file mode 100644 index a3e75d419a4497a77367e8e8d15018fac8093460..0000000000000000000000000000000000000000 --- a/runtime/mem/semi_space_collector-inl.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H -#define ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H - -#include "plugins/ecmascript/runtime/mem/semi_space_collector.h" - -#include "plugins/ecmascript/runtime/js_hclass-inl.h" -#include "plugins/ecmascript/runtime/mem/parallel_work_helper.h" - -namespace panda::ecmascript { -void SemiSpaceCollector::UpdatePromotedSlot(TaggedObject *object, ObjectSlot slot) -{ -#ifndef NDEBUG - JSTaggedValue value(slot.GetTaggedType()); - ASSERT(value.IsHeapObject()); -#endif - Region *objectRegion = Region::ObjectAddressToRange(object); - ASSERT(!objectRegion->InYoungGeneration()); - objectRegion->InsertOldToNewRememberedSet(slot.SlotAddress()); -} -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H diff --git a/runtime/mem/semi_space_collector.cpp b/runtime/mem/semi_space_collector.cpp deleted file mode 100644 index acc7d2905ea81f115ad5292a9d228d1160806e9e..0000000000000000000000000000000000000000 --- a/runtime/mem/semi_space_collector.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/semi_space_collector-inl.h" - -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/mem/clock_scope.h" -#include "plugins/ecmascript/runtime/mem/concurrent_marker.h" -#include "plugins/ecmascript/runtime/mem/mem_manager.h" -#include "plugins/ecmascript/runtime/mem/heap-inl.h" -#include "plugins/ecmascript/runtime/mem/object_xray-inl.h" -#include "plugins/ecmascript/runtime/mem/mark_stack.h" -#include "plugins/ecmascript/runtime/mem/mem.h" -#include "plugins/ecmascript/runtime/mem/parallel_marker-inl.h" -#include "plugins/ecmascript/runtime/mem/space-inl.h" -#include "plugins/ecmascript/runtime/mem/tlab_allocator-inl.h" -#include "plugins/ecmascript/runtime/runtime_call_id.h" -#include "plugins/ecmascript/runtime/vmstat/runtime_stat.h" - -namespace panda::ecmascript { -SemiSpaceCollector::SemiSpaceCollector(Heap *heap, bool paralledGc) - : heap_(heap), paralledGc_(paralledGc), workList_(heap->GetWorkList()) -{ -} - -void SemiSpaceCollector::RunPhases() -{ - [[maybe_unused]] ecmascript::JSThread *thread = heap_->GetEcmaVM()->GetJSThread(); - INTERPRETER_TRACE(thread, SemiSpaceCollector_RunPhases); - [[maybe_unused]] ClockScope clockScope; - - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "SemiSpaceCollector::RunPhases"); - bool concurrentMark = heap_->CheckConcurrentMark(thread); - if (concurrentMark) { - ECMA_GC_LOG() << "SemiSpaceCollector after ConcurrentMarking"; - heap_->GetConcurrentMarker()->Reset(); // HPPGC use mark result to move TaggedObject. - } - InitializePhase(); - ParallelMarkingPhase(); - SweepPhases(); - FinishPhase(); - heap_->GetEcmaVM()->GetEcmaGCStats()->StatisticSemiCollector(clockScope.GetPauseTime(), semiCopiedSize_, - promotedSize_, commitSize_); - ECMA_GC_LOG() << "SemiSpaceCollector::RunPhases " << clockScope.TotalSpentTime(); -} - -void SemiSpaceCollector::InitializePhase() -{ - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "SemiSpaceCollector::InitializePhase"); - heap_->Prepare(); - workList_->Initialize(TriggerGCType::SEMI_GC, ParallelGCTaskPhase::SEMI_HANDLE_GLOBAL_POOL_TASK); - heap_->GetSemiGcMarker()->Initialized(); - heap_->GetEvacuationAllocator()->Initialize(TriggerGCType::SEMI_GC); - promotedSize_ = 0; - semiCopiedSize_ = 0; - commitSize_ = heap_->GetFromSpace()->GetCommittedSize(); -} - -void SemiSpaceCollector::ParallelMarkingPhase() -{ - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "SemiSpaceCollector::ParallelMarkingPhase"); - auto region = heap_->GetOldSpace()->GetCurrentRegion(); - - if (paralledGc_) { - heap_->PostParallelGCTask(ParallelGCTaskPhase::SEMI_HANDLE_THREAD_ROOTS_TASK); - heap_->PostParallelGCTask(ParallelGCTaskPhase::SEMI_HANDLE_SNAPSHOT_TASK); - heap_->GetSemiGcMarker()->ProcessOldToNew(0, region); - } else { - heap_->GetSemiGcMarker()->ProcessOldToNew(0, region); - heap_->GetSemiGcMarker()->ProcessSnapshotRSet(0); - heap_->GetSemiGcMarker()->MarkRoots(0); - heap_->GetSemiGcMarker()->ProcessMarkStack(0); - } - heap_->WaitRunningTaskFinished(); - - auto totalThreadCount = Platform::GetCurrentPlatform()->GetTotalThreadNum() + 1; // gc thread and main thread - for (uint32_t i = 0; i < totalThreadCount; i++) { - SlotNeedUpdate needUpdate(nullptr, ObjectSlot(0)); - while (workList_->GetSlotNeedUpdate(i, &needUpdate)) { - UpdatePromotedSlot(needUpdate.first, needUpdate.second); - } - } -} - -void SemiSpaceCollector::SweepPhases() -{ - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "SemiSpaceCollector::SweepPhases"); - auto totalThreadCount = Platform::GetCurrentPlatform()->GetTotalThreadNum() + 1; // gc thread and main thread - for (uint32_t i = 0; i < totalThreadCount; i++) { - ProcessQueue *queue = workList_->GetWeakReferenceQueue(i); - while (true) { - auto obj = queue->PopBack(); - if (UNLIKELY(obj == nullptr)) { - break; - } - ObjectSlot slot(ToUintPtr(obj)); - JSTaggedValue value(slot.GetTaggedType()); - auto header = value.GetTaggedWeakRef(); - MarkWord markWord(header); - if (markWord.IsForwardingAddress()) { - TaggedObject *dst = markWord.ToForwardingAddress(); - auto weakRef = JSTaggedValue(JSTaggedValue(dst).CreateAndGetWeakRef()).GetRawTaggedObject(); - slot.Update(weakRef); - } else { - slot.Update(static_cast(JSTaggedValue::Undefined().GetRawData())); - } - } - } - - auto stringTable = heap_->GetEcmaVM()->GetEcmaStringTable(); - WeakRootVisitor gcUpdateWeak = [](TaggedObject *header) { - Region *objectRegion = Region::ObjectAddressToRange(reinterpret_cast(header)); - if (!objectRegion->InYoungGeneration()) { - return header; - } - - MarkWord markWord(header); - if (markWord.IsForwardingAddress()) { - TaggedObject *dst = markWord.ToForwardingAddress(); - return dst; - } - return reinterpret_cast(ToUintPtr(nullptr)); - }; - stringTable->SweepWeakReference(gcUpdateWeak); - heap_->GetEcmaVM()->GetJSThread()->IterateWeakEcmaGlobalStorage(gcUpdateWeak); - heap_->GetEcmaVM()->ProcessReferences(gcUpdateWeak); - heap_->UpdateDerivedObjectInStack(); -} - -void SemiSpaceCollector::FinishPhase() -{ - ECMA_BYTRACE_NAME(BYTRACE_TAG_ARK, "SemiSpaceCollector::FinishPhase"); - workList_->Finish(semiCopiedSize_, promotedSize_); - heap_->GetEvacuationAllocator()->Finalize(TriggerGCType::SEMI_GC); -} -} // namespace panda::ecmascript diff --git a/runtime/mem/semi_space_collector.h b/runtime/mem/semi_space_collector.h deleted file mode 100644 index 1c127ff74bf6eec97ae7e77c3caca517b394335d..0000000000000000000000000000000000000000 --- a/runtime/mem/semi_space_collector.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_H -#define ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_H - -#include "plugins/ecmascript/runtime/mem/clock_scope.h" -#include "plugins/ecmascript/runtime/mem/mem.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/allocator.h" -#include "plugins/ecmascript/runtime/mem/mark_stack-inl.h" -#include "plugins/ecmascript/runtime/mem/mark_word.h" -#include "plugins/ecmascript/runtime/mem/slots.h" -#include "plugins/ecmascript/runtime/mem/object_xray.h" -#include "plugins/ecmascript/runtime/mem/remembered_set.h" -#include "plugins/ecmascript/runtime/mem/chunk_containers.h" -#include "plugins/ecmascript/runtime/mem/tlab_allocator.h" - -#include "os/mutex.h" - -namespace panda::ecmascript { -class Heap; -class JSHClass; -class WorkerHelper; - -class GarbageCollector { -public: - GarbageCollector() = default; - virtual ~GarbageCollector() = default; - DEFAULT_COPY_SEMANTIC(GarbageCollector); - DEFAULT_MOVE_SEMANTIC(GarbageCollector); -}; - -class SemiSpaceCollector : public GarbageCollector { -public: - explicit SemiSpaceCollector(Heap *heap, bool paralledGc); - ~SemiSpaceCollector() override = default; - NO_COPY_SEMANTIC(SemiSpaceCollector); - NO_MOVE_SEMANTIC(SemiSpaceCollector); - - void RunPhases(); - -private: - void InitializePhase(); - void ParallelMarkingPhase(); - void SweepPhases(); - void FinishPhase(); - - inline void UpdatePromotedSlot(TaggedObject *object, ObjectSlot slot); - - Heap *heap_; - size_t promotedSize_ {0}; - size_t semiCopiedSize_ {0}; - size_t commitSize_ = 0; - - // obtain from heap - bool paralledGc_ {false}; - WorkerHelper *workList_ {nullptr}; - - friend class TlabAllocator; - friend class WorkerHelper; - friend class Heap; -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_H diff --git a/runtime/mem/space-inl.h b/runtime/mem/space-inl.h deleted file mode 100644 index 068644498775013c81d17c670d489096678cf1f3..0000000000000000000000000000000000000000 --- a/runtime/mem/space-inl.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_SPACE_INL_H -#define ECMASCRIPT_MEM_SPACE_INL_H - -#include "plugins/ecmascript/runtime/mem/space.h" - -namespace panda::ecmascript { -template -void Space::EnumerateRegions(const Callback &cb, Region *end) const -{ - Region *current = regionList_.GetFirst(); - if (end == nullptr) { - end = regionList_.GetLast(); - } - while (current != end) { - auto next = current->GetNext(); - cb(current); - current = next; - } - - if (current != nullptr) { - cb(current); - } -} - -template -void OldSpace::EnumerateCollectRegionSet(const Callback &cb) const -{ - for (Region *current : collectRegionSet_) { - if (current != nullptr) { - ASSERT(current->InCollectSet()); - cb(current); - } - } -} - -template -void OldSpace::EnumerateNonCollectRegionSet(const Callback &cb) const -{ - EnumerateRegions([&cb](Region *region) { - if (!region->InCollectSet()) { - cb(region); - } - }); -} -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_SPACE_INL_H diff --git a/runtime/mem/space.cpp b/runtime/mem/space.cpp deleted file mode 100644 index 5dd04f6cea579cc334c2cc2ddf263aacd9ef6d78..0000000000000000000000000000000000000000 --- a/runtime/mem/space.cpp +++ /dev/null @@ -1,631 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/mem/space-inl.h" - -#include "plugins/ecmascript/runtime/class_linker/program_object.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/mem_controller.h" -#include "plugins/ecmascript/runtime/mem/region-inl.h" -#include "plugins/ecmascript/runtime/mem/region_factory.h" -#include "plugins/ecmascript/runtime/mem/remembered_set.h" -#include "libpandabase/utils/logger.h" - -namespace panda::ecmascript { -Space::Space(Heap *heap, MemSpaceType spaceType, size_t initialCapacity, size_t maximumCapacity) - : heap_(heap), - vm_(heap_->GetEcmaVM()), - thread_(vm_->GetJSThread()), - regionFactory_(vm_->GetRegionFactory()), - spaceType_(spaceType), - initialCapacity_(initialCapacity), - maximumCapacity_(maximumCapacity) -{ -} - -void Space::AddRegion(Region *region) -{ - LOG_ECMA_MEM(DEBUG) << "Add region:" << region << " to " << ToSpaceTypeName(spaceType_); - regionList_.AddNode(region); - IncrementCommitted(region->GetCapacity()); -} - -void Space::AddRegionToFirst(Region *region) -{ - LOG_ECMA_MEM(DEBUG) << "Add region to first:" << region << " to " << ToSpaceTypeName(spaceType_); - regionList_.AddNodeToFirst(region); - IncrementCommitted(region->GetCapacity()); -} - -void Space::RemoveRegion(Region *region) -{ - LOG_ECMA_MEM(DEBUG) << "Remove region:" << region << " to " << ToSpaceTypeName(spaceType_); - if (regionList_.HasNode(region)) { - if (spaceType_ == MemSpaceType::OLD_SPACE || spaceType_ == MemSpaceType::NON_MOVABLE || - spaceType_ == MemSpaceType::MACHINE_CODE_SPACE) { - region->RebuildKind(); - } - regionList_.RemoveNode(region); - DecrementCommitted(region->GetCapacity()); - } -} - -void Space::Initialize() -{ - Region *region = regionFactory_->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE); - if (spaceType_ == MemSpaceType::SEMI_SPACE) { - region->SetFlag(RegionFlags::IS_IN_YOUNG_GENERATION); - } else if (spaceType_ == MemSpaceType::SNAPSHOT_SPACE) { - region->SetFlag(RegionFlags::IS_IN_SNAPSHOT_GENERATION); - } else if (spaceType_ == MemSpaceType::OLD_SPACE) { - region->InitializeKind(); - region->SetFlag(RegionFlags::IS_IN_OLD_GENERATION); - } else if (spaceType_ == MemSpaceType::MACHINE_CODE_SPACE) { - region->InitializeKind(); - region->SetFlag(RegionFlags::IS_IN_NON_MOVABLE_GENERATION); - // NOLINTNEXTLINE(clang-analyzer-deadcode.DeadStores) - [[maybe_unused]] int res = region->SetCodeExecutableAndReadable(); - LOG_ECMA_MEM(DEBUG) << "Initialize SetCodeExecutableAndReadable" << res; - } else if (spaceType_ == MemSpaceType::NON_MOVABLE) { - region->InitializeKind(); - region->SetFlag(RegionFlags::IS_IN_NON_MOVABLE_GENERATION); - } - - AddRegion(region); -} - -void Space::ReclaimRegions() -{ - EnumerateRegions([this](Region *current) { ClearAndFreeRegion(current); }); - regionList_.Clear(); - committedSize_ = 0; -} - -void Space::ClearAndFreeRegion(Region *region) -{ - LOG_ECMA_MEM(DEBUG) << "Clear region from:" << region << " to " << ToSpaceTypeName(spaceType_); - region->ClearMarkBitmap(); - region->ClearCrossRegionRememberedSet(); - region->ClearOldToNewRememberedSet(); - DecrementCommitted(region->GetCapacity()); - if (spaceType_ == MemSpaceType::OLD_SPACE || spaceType_ == MemSpaceType::NON_MOVABLE || - spaceType_ == MemSpaceType::MACHINE_CODE_SPACE) { - region->DestroyKind(); - } - regionFactory_->FreeRegion(region); -} - -size_t Space::GetHeapObjectSize() const -{ - Region *last = GetCurrentRegion(); - auto top = heap_->GetHeapManager()->GetNewSpaceAllocator().GetTop(); - size_t result = last->GetAllocatedBytes(top); - - EnumerateRegions([&result, &last](Region *current) { - if (current != last) { - result += current->GetAllocatedBytes(); - } - }); - - return result; -} - -SemiSpace::SemiSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacity) - : Space(heap, MemSpaceType::SEMI_SPACE, initialCapacity, maximumCapacity) -{ -} - -bool SemiSpace::Expand(uintptr_t top) -{ - if (committedSize_ >= maximumCapacity_) { - return false; - } - GetCurrentRegion()->SetHighWaterMark(top); - Region *region = regionFactory_->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE); - region->SetFlag(RegionFlags::IS_IN_YOUNG_GENERATION); - if (!thread_->IsReadyToMark()) { - region->SetMarking(true); - } - - AddRegion(region); - return true; -} - -bool SemiSpace::AddRegionToList(Region *region) -{ - ASSERT(region != nullptr); - if (GetCommittedSize() >= GetMaximumCapacity()) { - return false; - } - region->ResetFlag(); - region->SetFlag(RegionFlags::IS_IN_YOUNG_GENERATION); - region->SetFlag(RegionFlags::IS_IN_PROMOTE_SET); - region->SetSpace(this); - AddRegionToFirst(region); - return true; -} - -void SemiSpace::Swap([[maybe_unused]] SemiSpace *other) {} - -void SemiSpace::SetAgeMark(uintptr_t mark) -{ - ageMark_ = mark; - Region *last = GetCurrentRegion(); - last->SetFlag(RegionFlags::HAS_AGE_MARK); - - EnumerateRegions([&last](Region *current) { - if (current != last) { - current->SetFlag(RegionFlags::BELOW_AGE_MARK); - } - }); -} - -bool SemiSpace::ContainObject(TaggedObject *object) const -{ - auto region = GetRegionList().GetFirst(); - while (region != nullptr) { - if (region->InRange(ToUintPtr(object))) { - return true; - } - region = region->GetNext(); - } - - return false; -} - -bool SemiSpace::IsLive(TaggedObject *object) const -{ - auto region = GetRegionList().GetFirst(); - while (region != nullptr) { - if (region->InRange(ToUintPtr(object))) { - auto freeObject = FreeObject::Cast(ToUintPtr(object)); - return !freeObject->IsFreeObject(); - } - region = region->GetNext(); - } - return false; -} - -void SemiSpace::IterateOverObjects(const std::function &visitor) const -{ - auto current = GetCurrentRegion(); - EnumerateRegions([&](Region *region) { - auto curPtr = region->GetBegin(); - uintptr_t endPtr; - if (region == current) { - auto top = heap_->GetHeapManager()->GetNewSpaceAllocator().GetTop(); - endPtr = curPtr + region->GetAllocatedBytes(top); - } else { - endPtr = curPtr + region->GetAllocatedBytes(); - } - - size_t objSize; - while (curPtr < endPtr) { - auto freeObject = FreeObject::Cast(curPtr); - if (!freeObject->IsFreeObject()) { - auto obj = reinterpret_cast(curPtr); - visitor(obj); - objSize = obj->GetClass()->SizeFromJSHClass(obj); - } else { - objSize = freeObject->Available(); - } - curPtr += objSize; - // NOLINTNEXTLINE(bugprone-lambda-function-name) - CHECK_OBJECT_SIZE(objSize); - } - // NOLINTNEXTLINE(bugprone-lambda-function-name) - CHECK_REGION_END(curPtr, endPtr); - }); -} - -size_t SemiSpace::GetAllocatedSizeSinceGC() const -{ - Region *last = GetCurrentRegion(); - if (last->BelowAgeMark()) { - return 0; - } - auto top = GetHeap()->GetHeapManager()->GetNewSpaceAllocator().GetTop(); - size_t result = 0; - if (last->HasAgeMark()) { - result = last->GetAllocatedBytes(top) - last->GetAllocatedBytes(ageMark_); - return result; - } - result = last->GetAllocatedBytes(top); - EnumerateRegions([this, &result, &last](Region *current) { - if (!current->HasAgeMark() && !current->BelowAgeMark()) { - if (current != last) { - result += current->GetAllocatedBytes(); - } - } else if (current->HasAgeMark()) { - result += current->GetAllocatedBytes(); - result -= current->GetAllocatedBytes(this->GetAgeMark()); - } - }); - return result; -} - -OldSpace::OldSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacity) - : Space(heap, MemSpaceType::OLD_SPACE, initialCapacity, maximumCapacity) -{ -} - -bool OldSpace::Expand() -{ - if (committedSize_ >= maximumCapacity_) { - LOG_ECMA_MEM(FATAL) << "Committed size " << committedSize_ << " of old space is too big. "; - return false; - } - Region *region = regionFactory_->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE); - region->SetFlag(RegionFlags::IS_IN_OLD_GENERATION); - if (!thread_->IsReadyToMark()) { - region->SetMarking(true); - } - region->InitializeKind(); - AddRegion(region); - return true; -} - -bool OldSpace::AddRegionToList(Region *region) -{ - ASSERT(region != nullptr); - if (GetCommittedSize() >= GetMaximumCapacity()) { - LOG_ECMA_MEM(FATAL) << "Committed size " << GetCommittedSize() << " of old space is too big. "; - return false; - } - if (!region->InOldGeneration()) { - region->InitializeKind(); - } - region->ResetFlag(); - region->SetFlag(RegionFlags::IS_IN_OLD_GENERATION); - region->SetFlag(RegionFlags::IS_IN_PROMOTE_SET); - region->SetSpace(this); - AddRegionToFirst(region); - return true; -} - -bool OldSpace::ContainObject(TaggedObject *object) const -{ - auto region = GetRegionList().GetFirst(); - while (region != nullptr) { - if (region->InRange(ToUintPtr(object))) { - return true; - } - region = region->GetNext(); - } - return false; -} - -bool OldSpace::IsLive(TaggedObject *object) const -{ - auto region = GetRegionList().GetFirst(); - while (region != nullptr) { - if (region->InRange(ToUintPtr(object))) { - if (region->InCollectSet()) { - return false; - } - auto freeObject = FreeObject::Cast(ToUintPtr(object)); - return !freeObject->IsFreeObject(); - } - region = region->GetNext(); - } - return false; -} - -void OldSpace::IterateOverObjects(const std::function &visitor) const -{ - EnumerateRegions([&](Region *region) { - if (region->InCollectSet()) { - return; - } - uintptr_t curPtr = region->GetBegin(); - uintptr_t endPtr = region->GetEnd(); - while (curPtr < endPtr) { - auto freeObject = FreeObject::Cast(curPtr); - size_t objSize; - if (!freeObject->IsFreeObject()) { - auto obj = reinterpret_cast(curPtr); - visitor(obj); - objSize = obj->GetClass()->SizeFromJSHClass(obj); - } else { - objSize = freeObject->Available(); - } - curPtr += objSize; - // NOLINTNEXTLINE(bugprone-lambda-function-name) - CHECK_OBJECT_SIZE(objSize); - } - // NOLINTNEXTLINE(bugprone-lambda-function-name) - CHECK_REGION_END(curPtr, endPtr); - }); -} - -size_t OldSpace::GetHeapObjectSize() const -{ - size_t result; - size_t availableSize = heap_->GetHeapManager()->GetOldSpaceAllocator().GetAvailableSize(); - result = committedSize_ - availableSize; - return result; -} - -void OldSpace::Merge(Space *fromSpace) -{ - ASSERT(GetSpaceType() == fromSpace->GetSpaceType()); - fromSpace->EnumerateRegions([&](Region *region) { - fromSpace->DecrementCommitted(region->GetCapacity()); - AddRegion(region); - }); - fromSpace->GetRegionList().Clear(); -} - -void OldSpace::AddRegionToCSet(Region *region) -{ - region->SetFlag(RegionFlags::IS_IN_COLLECT_SET); - collectRegionSet_.emplace_back(region); -} - -void OldSpace::ClearRegionFromCSet() -{ - EnumerateCollectRegionSet([](Region *region) { region->ClearFlag(RegionFlags::IS_IN_COLLECT_SET); }); - collectRegionSet_.clear(); -} - -void OldSpace::RemoveRegionFromCSetAndList(Region *region) -{ - for (auto current = collectRegionSet_.begin(); current != collectRegionSet_.end(); current++) { - if (*current == region) { - region->ClearFlag(RegionFlags::IS_IN_COLLECT_SET); - current = collectRegionSet_.erase(current); - break; - } - } - RemoveRegion(region); -} - -void OldSpace::RemoveCSetFromList() -{ - EnumerateCollectRegionSet([this](Region *current) { GetRegionList().RemoveNode(current); }); -} - -void OldSpace::ReclaimRegionCSet() -{ - EnumerateCollectRegionSet([this](Region *current) { ClearAndFreeRegion(current); }); - collectRegionSet_.clear(); -} - -void OldSpace::SelectCSet() -{ - EnumerateRegions([this](Region *region) { - if (!region->MostObjectAlive()) { - collectRegionSet_.emplace_back(region); - } - }); - if (collectRegionSet_.size() < PARTIAL_GC_MIN_COLLECT_REGION_SIZE) { - heap_->SetOnlyMarkSemi(true); - collectRegionSet_.clear(); - return; - } - // sort - std::sort(collectRegionSet_.begin(), collectRegionSet_.end(), - [](Region *first, Region *second) { return first->AliveObject() < second->AliveObject(); }); - uint64_t selectedRegionNumber = GetSelectedRegionNumber(); - if (collectRegionSet_.size() > selectedRegionNumber) { - collectRegionSet_.resize(selectedRegionNumber); - } - for (Region *region : collectRegionSet_) { - region->SetFlag(RegionFlags::IS_IN_COLLECT_SET); - } -} - -NonMovableSpace::NonMovableSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacity) - : Space(heap, MemSpaceType::NON_MOVABLE, initialCapacity, maximumCapacity) -{ -} - -bool NonMovableSpace::Expand() -{ - if (committedSize_ >= maximumCapacity_) { - LOG_ECMA_MEM(FATAL) << "Committed size " << committedSize_ << " of non movable space is too big. "; - return false; - } - Region *region = regionFactory_->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE); - region->SetFlag(IS_IN_NON_MOVABLE_GENERATION); - if (!thread_->IsReadyToMark()) { - region->SetMarking(true); - } - region->InitializeKind(); - AddRegion(region); - return true; -} - -size_t NonMovableSpace::GetHeapObjectSize() const -{ - size_t result; - size_t availableSize = heap_->GetHeapManager()->GetNonMovableSpaceAllocator().GetAvailableSize(); - result = GetCommittedSize() - availableSize; - return result; -} - -SnapShotSpace::SnapShotSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacity) - : Space(heap, MemSpaceType::SNAPSHOT_SPACE, initialCapacity, maximumCapacity) -{ -} - -bool SnapShotSpace::Expand(uintptr_t top) -{ - if (committedSize_ >= maximumCapacity_) { - return false; - } - Region *current = GetCurrentRegion(); - if (current != nullptr) { - current->SetHighWaterMark(top); - } - Region *region = regionFactory_->AllocateAlignedRegion(this, DEFAULT_SNAPSHOT_SPACE_SIZE); - region->SetFlag(RegionFlags::IS_IN_SNAPSHOT_GENERATION); - if (!thread_->IsReadyToMark()) { - region->SetMarking(true); - } - AddRegion(region); - return true; -} - -void Space::Destroy() -{ - ReclaimRegions(); -} - -void NonMovableSpace::IterateOverObjects(const std::function &visitor) const -{ - EnumerateRegions([&](Region *region) { - uintptr_t curPtr = region->GetBegin(); - uintptr_t endPtr = region->GetEnd(); - while (curPtr < endPtr) { - auto freeObject = FreeObject::Cast(curPtr); - size_t objSize; - if (!freeObject->IsFreeObject()) { - auto obj = reinterpret_cast(curPtr); - visitor(obj); - objSize = obj->GetClass()->SizeFromJSHClass(obj); - } else { - objSize = freeObject->Available(); - } - curPtr += objSize; - // NOLINTNEXTLINE(bugprone-lambda-function-name) - CHECK_OBJECT_SIZE(objSize); - } - // NOLINTNEXTLINE(bugprone-lambda-function-name) - CHECK_REGION_END(curPtr, endPtr); - }); -} - -bool NonMovableSpace::ContainObject(TaggedObject *object) const -{ - auto region = GetRegionList().GetFirst(); - while (region != nullptr) { - if (region->InRange(ToUintPtr(object))) { - return true; - } - region = region->GetNext(); - } - return false; -} - -bool NonMovableSpace::IsLive(TaggedObject *object) const -{ - auto region = GetRegionList().GetFirst(); - while (region != nullptr) { - if (region->InRange(ToUintPtr(object))) { - auto freeObject = FreeObject::Cast(ToUintPtr(object)); - return !freeObject->IsFreeObject(); - } - region = region->GetNext(); - } - return false; -} - -HugeObjectSpace::HugeObjectSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacity) - : Space(heap, MemSpaceType::HUGE_OBJECT_SPACE, initialCapacity, maximumCapacity) -{ -} - -uintptr_t HugeObjectSpace::Allocate(size_t objectSize) -{ - if (committedSize_ >= maximumCapacity_) { - LOG_ECMA_MEM(FATAL) << "Committed size " << committedSize_ << " of huge object space is too big. " - << " old space committed: " << heap_->GetOldSpace()->GetCommittedSize() - << " old space limit: " << heap_->GetOldSpaceAllocLimit() - << " length: " << GetRegionList().GetLength(); - return 0; - } - size_t alignedSize = AlignUp(objectSize + sizeof(Region), PANDA_POOL_ALIGNMENT_IN_BYTES); - if (UNLIKELY(alignedSize > MAX_HUGE_OBJECT_SIZE)) { - LOG_ECMA_MEM(FATAL) << "The size is too big for this allocator. Return nullptr."; - return 0; - } - Region *region = regionFactory_->AllocateAlignedRegion(this, alignedSize); - region->SetFlag(RegionFlags::IS_HUGE_OBJECT); - if (!thread_->IsReadyToMark()) { - region->SetMarking(true); - } - AddRegion(region); - return region->GetBegin(); -} - -void HugeObjectSpace::Free(Region *region) -{ - GetRegionList().RemoveNode(region); - ClearAndFreeRegion(region); -} - -bool HugeObjectSpace::ContainObject(TaggedObject *object) const -{ - auto region = GetRegionList().GetFirst(); - while (region != nullptr) { - if (region->InRange(ToUintPtr(object))) { - return true; - } - region = region->GetNext(); - } - return false; -} - -bool HugeObjectSpace::IsLive(TaggedObject *object) const -{ - return ContainObject(object); -} - -size_t HugeObjectSpace::GetHeapObjectSize() const -{ - return committedSize_; -} - -void HugeObjectSpace::IterateOverObjects(const std::function &objectVisitor) const -{ - EnumerateRegions([&](Region *region) { - uintptr_t curPtr = region->GetBegin(); - objectVisitor(reinterpret_cast(curPtr)); - }); -} - -MachineCodeSpace::MachineCodeSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacity) - : Space(heap, MemSpaceType::MACHINE_CODE_SPACE, initialCapacity, maximumCapacity) -{ -} - -bool MachineCodeSpace::Expand() -{ - if (committedSize_ >= maximumCapacity_) { - LOG_ECMA_MEM(FATAL) << "Committed size " << committedSize_ << " of machine Code space is too big. "; - return false; - } - Region *region = regionFactory_->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE); - region->SetFlag(IS_IN_NON_MOVABLE_GENERATION); - region->InitializeKind(); - AddRegion(region); - if (!thread_->IsReadyToMark()) { - region->SetMarking(true); - } - // NOLINTNEXTLINE(clang-analyzer-deadcode.DeadStores) - [[maybe_unused]] int res = region->SetCodeExecutableAndReadable(); - LOG_ECMA_MEM(DEBUG) << "MachineCodeSpace::Expand() SetCodeExecutableAndReadable" << res; - return true; -} - -size_t MachineCodeSpace::GetHeapObjectSize() const -{ - size_t result = 0; - size_t availableSize = GetHeap()->GetHeapManager()->GetMachineCodeSpaceAllocator().GetAvailableSize(); - result = committedSize_ - availableSize; - return result; -} -} // namespace panda::ecmascript diff --git a/runtime/mem/space.h b/runtime/mem/space.h deleted file mode 100644 index 69b78779b648e70e7cd56e6a7d9405093f3eda75..0000000000000000000000000000000000000000 --- a/runtime/mem/space.h +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_SPACE_H -#define ECMASCRIPT_MEM_SPACE_H - -#include "mem/gc/bitmap.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" -#include "plugins/ecmascript/runtime/mem/ecma_list.h" -#include "plugins/ecmascript/runtime/mem/mem.h" -#include "plugins/ecmascript/runtime/mem/region.h" -#include "libpandabase/utils/type_helpers.h" -#include "libpandafile/file.h" - -namespace panda::ecmascript { -class EcmaVM; -class Heap; -class Program; - -enum MemSpaceType { - OLD_SPACE = 0, - NON_MOVABLE, - MACHINE_CODE_SPACE, - HUGE_OBJECT_SPACE, - SEMI_SPACE, - SNAPSHOT_SPACE, - COMPRESS_SPACE, - SPACE_TYPE_LAST, // Count of different types - - FREE_LIST_NUM = MACHINE_CODE_SPACE - OLD_SPACE + 1, -}; - -enum TriggerGCType { - SEMI_GC, - OLD_GC, - NON_MOVE_GC, - HUGE_GC, - MACHINE_CODE_GC, - COMPRESS_FULL_GC, - GC_TYPE_LAST // Count of different types -}; - -static inline std::string ToSpaceTypeName(MemSpaceType type) -{ - switch (type) { - case OLD_SPACE: - return "old space"; - case NON_MOVABLE: - return "non movable space"; - case MACHINE_CODE_SPACE: - return "machine code space"; - case HUGE_OBJECT_SPACE: - return "huge object space"; - case SEMI_SPACE: - return "semi space"; - case SNAPSHOT_SPACE: - return "snapshot space"; - case COMPRESS_SPACE: - return "compress space"; - default: - return "unknow space"; - } -} - -static constexpr size_t SPACE_TYPE_SIZE = helpers::ToUnderlying(MemSpaceType::SPACE_TYPE_LAST); - -class Space { -public: - Space(Heap *heap, MemSpaceType spaceType, size_t initialCapacity, size_t maximumCapacity); - virtual ~Space() = default; - NO_COPY_SEMANTIC(Space); - NO_MOVE_SEMANTIC(Space); - - Heap *GetHeap() const - { - return heap_; - } - - size_t GetMaximumCapacity() const - { - return maximumCapacity_; - } - - void SetMaximumCapacity(size_t maximumCapacity) - { - maximumCapacity_ = maximumCapacity; - } - - size_t GetInitialCapacity() const - { - return initialCapacity_; - } - - size_t GetCommittedSize() const - { - return committedSize_; - } - - void IncrementCommitted(size_t bytes) - { - committedSize_ += bytes; - } - - void DecrementCommitted(size_t bytes) - { - committedSize_ -= bytes; - } - - MemSpaceType GetSpaceType() const - { - return spaceType_; - } - - uintptr_t GetAllocateAreaBegin() const - { - return regionList_.GetLast()->GetBegin(); - } - - uintptr_t GetAllocateAreaEnd() const - { - return regionList_.GetLast()->GetEnd(); - } - - Region *GetCurrentRegion() const - { - return regionList_.GetLast(); - } - - uint32_t GetRegionCount() - { - return regionList_.GetLength(); - } - - EcmaList &GetRegionList() - { - return regionList_; - } - - const EcmaList &GetRegionList() const - { - return regionList_; - } - - size_t GetHeapObjectSize() const; - - template - void EnumerateRegions(const Callback &cb, Region *end = nullptr) const; - - void AddRegion(Region *region); - void AddRegionToFirst(Region *region); - void RemoveRegion(Region *region); - - void Initialize(); - void Destroy(); - - void ReclaimRegions(); - - void ClearAndFreeRegion(Region *region); - -protected: - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - Heap *heap_ {nullptr}; - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - EcmaVM *vm_ {nullptr}; - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - JSThread *thread_ {nullptr}; - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - RegionFactory *regionFactory_ {nullptr}; - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - EcmaList regionList_ {}; - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - MemSpaceType spaceType_ {}; - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - size_t initialCapacity_ {0}; - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - size_t maximumCapacity_ {0}; - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - size_t committedSize_ {0}; - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) -}; - -class SemiSpace : public Space { -public: - explicit SemiSpace(Heap *heap, size_t initialCapacity = DEFAULT_SEMI_SPACE_SIZE, - size_t maximumCapacity = SEMI_SPACE_SIZE_CAPACITY); - ~SemiSpace() override = default; - NO_COPY_SEMANTIC(SemiSpace); - NO_MOVE_SEMANTIC(SemiSpace); - - void SetAgeMark(uintptr_t mark); - - uintptr_t GetAgeMark() const - { - return ageMark_; - } - - bool Expand(uintptr_t top); - bool AddRegionToList(Region *region); - - void Swap(SemiSpace *other); - - bool ContainObject(TaggedObject *object) const; - bool IsLive(TaggedObject *object) const; - void IterateOverObjects(const std::function &objectVisitor) const; - - size_t GetAllocatedSizeSinceGC() const; - -private: - uintptr_t ageMark_ {0}; -}; - -class OldSpace : public Space { -public: - explicit OldSpace(Heap *heap, size_t initialCapacity = DEFAULT_OLD_SPACE_SIZE, - size_t maximumCapacity = MAX_OLD_SPACE_SIZE); - ~OldSpace() override = default; - NO_COPY_SEMANTIC(OldSpace); - NO_MOVE_SEMANTIC(OldSpace); - bool Expand(); - bool AddRegionToList(Region *region); - bool ContainObject(TaggedObject *object) const; - bool IsLive(TaggedObject *object) const; - void IterateOverObjects(const std::function &objectVisitor) const; - size_t GetHeapObjectSize() const; - void Merge(Space *fromSpace); - void AddRegionToCSet(Region *region); - void RemoveRegionFromCSetAndList(Region *region); - void ClearRegionFromCSet(); - void RemoveCSetFromList(); - void ReclaimRegionCSet(); - template - void EnumerateCollectRegionSet(const Callback &cb) const; - template - void EnumerateNonCollectRegionSet(const Callback &cb) const; - void SelectCSet(); - size_t GetSelectedRegionNumber() const - { - return std::max(committedSize_ / PARTIAL_GC_MAX_COLLECT_REGION_RATE, PARTIAL_GC_INITIAL_COLLECT_REGION_SIZE); - } - -private: - static constexpr size_t PARTIAL_GC_MAX_COLLECT_REGION_RATE = 1024 * 1024 * 2; - static constexpr size_t PARTIAL_GC_INITIAL_COLLECT_REGION_SIZE = 16; - static constexpr size_t PARTIAL_GC_MIN_COLLECT_REGION_SIZE = 5; - CVector collectRegionSet_; -}; - -class NonMovableSpace : public Space { -public: - explicit NonMovableSpace(Heap *heap, size_t initialCapacity = DEFAULT_NON_MOVABLE_SPACE_SIZE, - size_t maximumCapacity = MAX_NON_MOVABLE_SPACE_SIZE); - ~NonMovableSpace() override = default; - NO_COPY_SEMANTIC(NonMovableSpace); - NO_MOVE_SEMANTIC(NonMovableSpace); - bool Expand(); - bool ContainObject(TaggedObject *object) const; - bool IsLive(TaggedObject *object) const; - void IterateOverObjects(const std::function &objectVisitor) const; - size_t GetHeapObjectSize() const; -}; - -class SnapShotSpace : public Space { -public: - explicit SnapShotSpace(Heap *heap, size_t initialCapacity = DEFAULT_SNAPSHOT_SPACE_SIZE, - size_t maximumCapacity = MAX_SNAPSHOT_SPACE_SIZE); - ~SnapShotSpace() override = default; - NO_COPY_SEMANTIC(SnapShotSpace); - NO_MOVE_SEMANTIC(SnapShotSpace); - bool Expand(uintptr_t top); -}; - -class HugeObjectSpace : public Space { -public: - explicit HugeObjectSpace(Heap *heap, size_t initialCapacity = DEFAULT_OLD_SPACE_SIZE, - size_t maximumCapacity = MAX_HUGE_OBJECT_SPACE_SIZE); - ~HugeObjectSpace() override = default; - NO_COPY_SEMANTIC(HugeObjectSpace); - NO_MOVE_SEMANTIC(HugeObjectSpace); - uintptr_t Allocate(size_t objectSize); - void Free(Region *region); - size_t GetHeapObjectSize() const; - bool ContainObject(TaggedObject *object) const; - bool IsLive(TaggedObject *object) const; - void IterateOverObjects(const std::function &objectVisitor) const; -}; - -class MachineCodeSpace : public Space { -public: - explicit MachineCodeSpace(Heap *heap, size_t initialCapacity = DEFAULT_MACHINE_CODE_SPACE_SIZE, - size_t maximumCapacity = MAX_MACHINE_CODE_SPACE_SIZE); - ~MachineCodeSpace() override = default; - NO_COPY_SEMANTIC(MachineCodeSpace); - NO_MOVE_SEMANTIC(MachineCodeSpace); // Note: Expand(), ContainObject(), IsLive() left for define - bool Expand(); - size_t GetHeapObjectSize() const; -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_SPACE_H diff --git a/runtime/mem/tagged_object-inl.h b/runtime/mem/tagged_object-inl.h index 1bc2c457faae66ba0d9a34fdb8197ee3ca83061b..dd79d8a8696415fde6d217e99b647f0a34fc7b57 100644 --- a/runtime/mem/tagged_object-inl.h +++ b/runtime/mem/tagged_object-inl.h @@ -21,7 +21,6 @@ #include #include "plugins/ecmascript/runtime/js_hclass.h" #include "plugins/ecmascript/runtime/js_handle.h" -#include "heap.h" namespace panda::ecmascript { inline void TaggedObject::SetClassWithoutBarrier(JSHClass *hclass) diff --git a/runtime/mem/tagged_object.h b/runtime/mem/tagged_object.h index 241c6cfb81e2c7e1c96d097c5898811ebd54fd5d..024bf6d99485c10f687e6c84f4353a8550ae3449 100644 --- a/runtime/mem/tagged_object.h +++ b/runtime/mem/tagged_object.h @@ -16,7 +16,6 @@ #ifndef ECMASCRIPT_TAGGED_OBJECT_HEADER_H #define ECMASCRIPT_TAGGED_OBJECT_HEADER_H -#include "plugins/ecmascript/runtime/mem/mark_word.h" #include "include/object_header.h" namespace panda::ecmascript { diff --git a/runtime/mem/tlab_allocator-inl.h b/runtime/mem/tlab_allocator-inl.h deleted file mode 100644 index 23e88678ca08e48f4b44deadf3f87294a8e50a69..0000000000000000000000000000000000000000 --- a/runtime/mem/tlab_allocator-inl.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_TLAB_ALLOCATOR_INL_H -#define ECMASCRIPT_MEM_TLAB_ALLOCATOR_INL_H - -#include "plugins/ecmascript/runtime/mem/tlab_allocator.h" - -#include - -#include "plugins/ecmascript/runtime/free_object.h" -#include "plugins/ecmascript/runtime/mem/compress_collector.h" -#include "plugins/ecmascript/runtime/mem/evacuation_allocator-inl.h" - -namespace panda::ecmascript { -static constexpr size_t YOUNG_BUFFER_SIZE = 31 * 1024; -static constexpr size_t OLD_BUFFER_SIZE = 255 * 1024; - -TlabAllocator::TlabAllocator(Heap *heap, TriggerGCType gcType) - : heap_(heap), gcType_(gcType), youngEnable_(true), allocator_(heap_->GetEvacuationAllocator()) -{ -} - -TlabAllocator::~TlabAllocator() -{ - Finalize(); -} - -inline void TlabAllocator::Finalize() -{ - if (youngerAllocator_.Available() != 0) { - FreeObject::FillFreeObject(heap_->GetEcmaVM(), youngerAllocator_.GetTop(), youngerAllocator_.Available()); - youngerAllocator_.Reset(); - } - if (oldBumpPointerAllocator_.Available() != 0) { - allocator_->FreeSafe(oldBumpPointerAllocator_.GetTop(), oldBumpPointerAllocator_.GetEnd()); - Region *current = Region::ObjectAddressToRange(oldBumpPointerAllocator_.GetTop()); - current->DecreaseAliveObject(oldBumpPointerAllocator_.Available()); - oldBumpPointerAllocator_.Reset(); - } -} - -uintptr_t TlabAllocator::Allocate(size_t size, SpaceAlloc spaceAlloc) -{ - uintptr_t result = 0; - switch (spaceAlloc) { - case SpaceAlloc::YOUNG_SPACE: - result = TlabAllocatorYoungSpace(size); - break; - case SpaceAlloc::OLD_SPACE: - result = TlabAllocatorOldSpace(size); - break; - default: - UNREACHABLE(); - } - return result; -} - -uintptr_t TlabAllocator::TlabAllocatorYoungSpace(size_t size) -{ - size = AlignUp(size, static_cast(MemAlignment::MEM_ALIGN_OBJECT)); - if (UNLIKELY(size >= SMALL_OBJECT_SIZE)) { - uintptr_t address = allocator_->AllocateYoung(size); - LOG(DEBUG, RUNTIME) << "AllocatorYoungSpace:" << address; - return address; - } - uintptr_t result = youngerAllocator_.Allocate(size); - if (result != 0) { - return result; - } - if (youngerAllocator_.Available() != 0) { - FreeObject::FillFreeObject(heap_->GetEcmaVM(), youngerAllocator_.GetTop(), youngerAllocator_.Available()); - } - if (!youngEnable_ || !ExpandYoung()) { - youngEnable_ = false; - return 0; - } - return youngerAllocator_.Allocate(size); -} - -uintptr_t TlabAllocator::TlabAllocatorOldSpace(size_t size) -{ - size = AlignUp(size, static_cast(MemAlignment::MEM_ALIGN_OBJECT)); - uintptr_t result = oldBumpPointerAllocator_.Allocate(size); - if (result != 0) { - FreeObject::FillFreeObject(heap_->GetEcmaVM(), oldBumpPointerAllocator_.GetTop(), - oldBumpPointerAllocator_.Available()); - return result; - } - Region *current = Region::ObjectAddressToRange(oldBumpPointerAllocator_.GetTop()); - if (current != nullptr) { - current->DecreaseAliveObject(oldBumpPointerAllocator_.Available()); - } - allocator_->FreeSafe(oldBumpPointerAllocator_.GetTop(), oldBumpPointerAllocator_.GetEnd()); - if (!ExpandOld()) { - return 0; - } - result = oldBumpPointerAllocator_.Allocate(size); - if (result != 0) { - FreeObject::FillFreeObject(heap_->GetEcmaVM(), oldBumpPointerAllocator_.GetTop(), - oldBumpPointerAllocator_.Available()); - } - return result; -} - -bool TlabAllocator::ExpandYoung() -{ - uintptr_t buffer = 0; - buffer = allocator_->AllocateYoung(YOUNG_BUFFER_SIZE); - - if (buffer == 0) { - return false; - } - youngerAllocator_.Reset(buffer, buffer + YOUNG_BUFFER_SIZE); - return true; -} - -bool TlabAllocator::ExpandOld() -{ - uintptr_t buffer = 0; - if (gcType_ == TriggerGCType::SEMI_GC) { - buffer = allocator_->AllocateOld(YOUNG_BUFFER_SIZE); - if (buffer == 0) { - return false; - } - oldBumpPointerAllocator_.Reset(buffer, buffer + YOUNG_BUFFER_SIZE); - FreeObject::FillFreeObject(heap_->GetEcmaVM(), oldBumpPointerAllocator_.GetTop(), - oldBumpPointerAllocator_.Available()); - } else if (gcType_ == TriggerGCType::COMPRESS_FULL_GC) { - Region *region = allocator_->ExpandOldSpace(); - if (region == nullptr) { - return false; - } - region->SetAliveObject(region->GetSize()); - oldBumpPointerAllocator_.Reset(region->GetBegin(), region->GetEnd()); - FreeObject::FillFreeObject(heap_->GetEcmaVM(), oldBumpPointerAllocator_.GetTop(), - oldBumpPointerAllocator_.Available()); - } else { - UNREACHABLE(); - } - - return true; -} -} // namespace panda::ecmascript -#endif // ECMASCRIPT_MEM_TLAB_ALLOCATOR_INL_H diff --git a/runtime/mem/tlab_allocator.h b/runtime/mem/tlab_allocator.h deleted file mode 100644 index 70f5579fe69a0a8aa6dad110990682eb1d03e578..0000000000000000000000000000000000000000 --- a/runtime/mem/tlab_allocator.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_TLAB_ALLOCATOR_H -#define ECMASCRIPT_MEM_TLAB_ALLOCATOR_H - -#include "plugins/ecmascript/runtime/mem/allocator-inl.h" - -namespace panda::ecmascript { -enum class SpaceAlloc : bool { - YOUNG_SPACE, - OLD_SPACE, -}; - -class Heap; -class EvacuationAllocator; - -class TlabAllocator { -public: - TlabAllocator() = delete; - inline ~TlabAllocator(); - NO_COPY_SEMANTIC(TlabAllocator); - NO_MOVE_SEMANTIC(TlabAllocator); - - inline void Finalize(); - - inline explicit TlabAllocator(Heap *heap, TriggerGCType gcType); - - inline uintptr_t Allocate(size_t size, SpaceAlloc spaceAlloc); - -private: - inline uintptr_t TlabAllocatorYoungSpace(size_t size); - inline uintptr_t TlabAllocatorOldSpace(size_t size); - - inline bool ExpandYoung(); - inline bool ExpandOld(); - - Heap *heap_; - TriggerGCType gcType_; - bool youngEnable_; - - BumpPointerAllocator youngerAllocator_; - BumpPointerAllocator oldBumpPointerAllocator_; - EvacuationAllocator *allocator_; -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_TLAB_ALLOCATOR_H diff --git a/runtime/mem/verification.cpp b/runtime/mem/verification.cpp deleted file mode 100644 index 990abbcbd93f1a50730bfb97e6beb75145743b95..0000000000000000000000000000000000000000 --- a/runtime/mem/verification.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "verification.h" - -#include "plugins/ecmascript/runtime/js_tagged_value-inl.h" -#include "plugins/ecmascript/runtime/mem/object_xray-inl.h" -#include "plugins/ecmascript/runtime/mem/slots.h" - -namespace panda::ecmascript { -// Verify the object body -void VerifyObjectVisitor::VisitAllObjects(TaggedObject *obj) -{ - auto jsHclass = obj->GetClass(); - objXRay_.VisitObjectBody( - obj, jsHclass, [this]([[maybe_unused]] TaggedObject *root, ObjectSlot start, ObjectSlot end) { - for (ObjectSlot slot = start; slot < end; slot++) { - JSTaggedValue value(slot.GetTaggedType()); - if (value.IsWeak()) { - if (!heap_->IsLive(value.GetTaggedWeakRef())) { - LOG(ERROR, RUNTIME) << "Heap verify detected a dead object at " << value.GetTaggedObject() - << "at object:" << slot.SlotAddress(); - ++(*failCount_); - } - } else if (value.IsHeapObject()) { - if (!heap_->IsLive(value.GetTaggedObject())) { - LOG(ERROR, RUNTIME) << "Heap verify detected a dead object at " << value.GetTaggedObject() - << "at object:" << slot.SlotAddress(); - ++(*failCount_); - } - } - } - }); -} - -size_t Verification::VerifyRoot() const -{ - size_t failCount = 0; - RootVisitor visit1 = [this, &failCount]([[maybe_unused]] Root type, ObjectSlot slot) { - JSTaggedValue value(slot.GetTaggedType()); - if (value.IsWeak()) { - VerifyObjectVisitor(heap_, &failCount)(value.GetTaggedWeakRef()); - } else if (value.IsHeapObject()) { - VerifyObjectVisitor(heap_, &failCount)(value.GetTaggedObject()); - } - }; - RootRangeVisitor visit2 = [this, &failCount]([[maybe_unused]] Root type, ObjectSlot start, ObjectSlot end) { - for (ObjectSlot slot = start; slot < end; slot++) { - JSTaggedValue value(slot.GetTaggedType()); - if (value.IsWeak()) { - VerifyObjectVisitor(heap_, &failCount)(value.GetTaggedWeakRef()); - } else if (value.IsHeapObject()) { - VerifyObjectVisitor(heap_, &failCount)(value.GetTaggedObject()); - } - } - }; - objXRay_.VisitVMRoots(visit1, visit2); - if (failCount > 0) { - LOG(ERROR, RUNTIME) << "VerifyRoot detects deadObject count is " << failCount; - } - - return failCount; -} - -size_t Verification::VerifyHeap() const -{ - size_t failCount = heap_->VerifyHeapObjects(); - if (failCount > 0) { - LOG(ERROR, RUNTIME) << "VerifyHeap detects deadObject count is " << failCount; - } - return failCount; -} - -bool Verification::IsHeapAddress(void *addr) const -{ - return heap_->ContainObject(reinterpret_cast(addr)); -} -} // namespace panda::ecmascript diff --git a/runtime/mem/verification.h b/runtime/mem/verification.h deleted file mode 100644 index 5a6c65bd305db67045809bbc4e3a9ebc9368cd26..0000000000000000000000000000000000000000 --- a/runtime/mem/verification.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_MEM_HEAP_VERIFICATION_H -#define ECMASCRIPT_MEM_HEAP_VERIFICATION_H - -#include - -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/object_xray.h" -#include "plugins/ecmascript/runtime/mem/mem.h" -#include "plugins/ecmascript/runtime/mem/slots.h" - -namespace panda::ecmascript { -// Verify the object body -// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions) -class VerifyObjectVisitor { -public: - VerifyObjectVisitor(const Heap *heap, size_t *failCount) - : heap_(heap), failCount_(failCount), objXRay_(heap->GetEcmaVM()) - { - } - ~VerifyObjectVisitor() = default; - - void operator()(TaggedObject *obj) - { - VisitAllObjects(obj); - } - - size_t GetFailedCount() const - { - return *failCount_; - } - -private: - void VisitAllObjects(TaggedObject *obj); - - const Heap *const heap_ {nullptr}; - size_t *const failCount_ {nullptr}; - ObjectXRay objXRay_; -}; - -class Verification { -public: - explicit Verification(const Heap *heap) : heap_(heap), objXRay_(heap->GetEcmaVM()) {} - ~Verification() = default; - - size_t VerifyAll() const - { - size_t result = VerifyRoot(); - result += VerifyHeap(); - return result; - } - - bool IsHeapAddress(void *addr) const; - size_t VerifyRoot() const; - size_t VerifyHeap() const; - -private: - NO_COPY_SEMANTIC(Verification); - NO_MOVE_SEMANTIC(Verification); - - const Heap *heap_ {nullptr}; - ObjectXRay objXRay_; -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_MEM_HEAP_VERIFICATION_H diff --git a/runtime/napi/jsnapi.cpp b/runtime/napi/jsnapi.cpp index 63290665db26d065e9587afd20046ec85c63f357..2a1a49af115de52c8179b8e18f476872b18ab01b 100644 --- a/runtime/napi/jsnapi.cpp +++ b/runtime/napi/jsnapi.cpp @@ -48,7 +48,6 @@ #include "plugins/ecmascript/runtime/js_tagged_number.h" #include "plugins/ecmascript/runtime/js_thread.h" #include "plugins/ecmascript/runtime/js_typed_array.h" -#include "plugins/ecmascript/runtime/mem/region.h" #include "plugins/ecmascript/runtime/object_factory.h" #include "plugins/ecmascript/runtime/tagged_array.h" @@ -58,7 +57,6 @@ #include "utils/pandargs.h" namespace panda { -using ecmascript::CString; using ecmascript::EcmaString; using ecmascript::ErrorType; using ecmascript::FastRuntimeStub; @@ -201,13 +199,13 @@ void JSNApi::TriggerGC(const EcmaVM *vm, TRIGGER_GC_TYPE gcType) ScopedManagedCodeThread s(vm->GetAssociatedThread()); switch (gcType) { case TRIGGER_GC_TYPE::SEMI_GC: - vm->CollectGarbage(ecmascript::TriggerGCType::SEMI_GC); + vm->CollectGarbage(); break; case TRIGGER_GC_TYPE::OLD_GC: - vm->CollectGarbage(ecmascript::TriggerGCType::OLD_GC); + vm->CollectGarbage(); break; case TRIGGER_GC_TYPE::COMPRESS_FULL_GC: - vm->CollectGarbage(ecmascript::TriggerGCType::COMPRESS_FULL_GC); + vm->CollectGarbage(); break; default: break; @@ -1510,7 +1508,6 @@ JSTaggedValue Callback::RegisterCallbackWithProperty(ecmascript::EcmaRuntimeCall return JSTaggedValue::False(); } JSHandle extraInfo(extraInfoValue); - // vm EcmaVM *vm = thread->GetEcmaVM(); // data JSHandle data(thread, extraInfo->GetData()); @@ -1556,7 +1553,6 @@ JSTaggedValue Callback::RegisterCallbackWithNewTarget(ecmascript::EcmaRuntimeCal return JSTaggedValue::False(); } JSHandle extraInfo(extraInfoValue); - // vm EcmaVM *vm = thread->GetEcmaVM(); // data JSHandle data(thread, extraInfo->GetData()); diff --git a/runtime/object_factory-inl.h b/runtime/object_factory-inl.h index d32e1cf65c466432b2b46c22643d521987bed47a..86e98c587944c80b53ab5df88a3a920c6f98c373 100644 --- a/runtime/object_factory-inl.h +++ b/runtime/object_factory-inl.h @@ -67,7 +67,7 @@ LexicalEnv *ObjectFactory::InlineNewLexicalEnv(int numSlots) template void ObjectFactory::NewJSIntlIcuData(const JSHandle &obj, const S &icu, const DeleteEntryPoint &callback) { - S *icuPoint = vm_->GetRegionFactory()->New(icu); + S *icuPoint = Runtime::GetCurrent()->GetInternalAllocator()->New(icu); ASSERT(icuPoint != nullptr); JSTaggedValue data = obj->GetIcuField(); if (data.IsHeapObject() && data.IsJSNativePointer()) { diff --git a/runtime/object_factory.cpp b/runtime/object_factory.cpp index c93e1b01d69c1170510230a7ff1755b5414fb2d8..d90d851ea0d10a2be0ad62446e8239278e8d84e8 100644 --- a/runtime/object_factory.cpp +++ b/runtime/object_factory.cpp @@ -17,7 +17,6 @@ #include "ecma_vm.h" #include "include/stack_walker.h" #include "js_method.h" -#include "mem/mark_word.h" #include "plugins/ecmascript/runtime/accessor_data.h" #include "plugins/ecmascript/runtime/base/error_helper.h" #include "plugins/ecmascript/runtime/builtins.h" @@ -73,8 +72,6 @@ #include "plugins/ecmascript/runtime/layout_info-inl.h" #include "plugins/ecmascript/runtime/linked_hash_table-inl.h" #include "plugins/ecmascript/runtime/mem/mem_manager.h" -#include "plugins/ecmascript/runtime/mem/heap-inl.h" -#include "plugins/ecmascript/runtime/mem/space.h" #include "plugins/ecmascript/runtime/record.h" #include "plugins/ecmascript/runtime/symbol_table-inl.h" #include "plugins/ecmascript/runtime/template_map.h" @@ -91,8 +88,13 @@ using EvalError = builtins::BuiltinsEvalError; using ErrorType = base::ErrorType; using ErrorHelper = base::ErrorHelper; -ObjectFactory::ObjectFactory(JSThread *thread, Heap *heap) - : thread_(thread), heapHelper_(heap), vm_(thread->GetEcmaVM()), heap_(heap) +static void PandaFreeBufferFunc([[maybe_unused]] void *buffer, [[maybe_unused]] void *data) +{ + Runtime::GetCurrent()->GetInternalAllocator()->Free(buffer); +} + +ObjectFactory::ObjectFactory(JSThread *thread) + : thread_(thread), heapHelper_(thread->GetEcmaVM()), vm_(thread->GetEcmaVM()) { } @@ -195,7 +197,7 @@ void ObjectFactory::NewJSArrayBufferData(const JSHandle &array, i JSTaggedValue data = array->GetArrayBufferData(); if (data != JSTaggedValue::Undefined()) { auto *pointer = JSNativePointer::Cast(data.GetTaggedObject()); - auto newData = vm_->GetRegionFactory()->AllocateBuffer(length * sizeof(uint8_t)); + auto newData = Runtime::GetCurrent()->GetInternalAllocator()->Alloc(length * sizeof(uint8_t)); if (memset_s(newData, length, 0, length) != EOK) { LOG_ECMA(FATAL) << "memset_s failed"; UNREACHABLE(); @@ -204,13 +206,12 @@ void ObjectFactory::NewJSArrayBufferData(const JSHandle &array, i return; } - auto newData = vm_->GetRegionFactory()->AllocateBuffer(length * sizeof(uint8_t)); + auto newData = Runtime::GetCurrent()->GetInternalAllocator()->Alloc(length * sizeof(uint8_t)); if (memset_s(newData, length, 0, length) != EOK) { LOG_ECMA(FATAL) << "memset_s failed"; UNREACHABLE(); } - JSHandle pointer = - NewJSNativePointer(newData, RegionFactory::FreeBufferFunc, vm_->GetRegionFactory()); + JSHandle pointer = NewJSNativePointer(newData, PandaFreeBufferFunc); array->SetArrayBufferData(thread_, pointer.GetTaggedValue()); vm_->PushToArrayDataList(*pointer); } @@ -224,13 +225,12 @@ JSHandle ObjectFactory::NewJSArrayBuffer(int32_t length) JSHandle arrayBuffer(NewJSObjectByConstructor(constructor, newTarget)); arrayBuffer->SetArrayBufferByteLength(thread_, JSTaggedValue(length)); if (length > 0) { - auto newData = vm_->GetRegionFactory()->AllocateBuffer(length); + auto newData = Runtime::GetCurrent()->GetInternalAllocator()->Alloc(length); if (memset_s(newData, length, 0, length) != EOK) { LOG_ECMA(FATAL) << "memset_s failed"; UNREACHABLE(); } - JSHandle pointer = - NewJSNativePointer(newData, RegionFactory::FreeBufferFunc, vm_->GetRegionFactory()); + JSHandle pointer = NewJSNativePointer(newData, PandaFreeBufferFunc); arrayBuffer->SetArrayBufferData(thread_, pointer.GetTaggedValue()); arrayBuffer->SetShared(thread_, JSTaggedValue::False()); vm_->PushToArrayDataList(*pointer); @@ -286,7 +286,7 @@ void ObjectFactory::NewJSRegExpByteCodeData(const JSHandle ®exp, vo return; } - auto newBuffer = vm_->GetRegionFactory()->AllocateBuffer(size); + auto newBuffer = Runtime::GetCurrent()->GetInternalAllocator()->Alloc(size); if (memcpy_s(newBuffer, size, buffer, size) != EOK) { LOG_ECMA(FATAL) << "memcpy_s failed"; UNREACHABLE(); @@ -297,8 +297,7 @@ void ObjectFactory::NewJSRegExpByteCodeData(const JSHandle ®exp, vo native->ResetExternalPointer(newBuffer); return; } - JSHandle pointer = - NewJSNativePointer(newBuffer, RegionFactory::FreeBufferFunc, vm_->GetRegionFactory()); + JSHandle pointer = NewJSNativePointer(newBuffer, PandaFreeBufferFunc); regexp->SetByteCodeBuffer(thread_, pointer.GetTaggedValue()); regexp->SetLength(thread_, JSTaggedValue(static_cast(size))); @@ -1586,14 +1585,6 @@ JSHandle ObjectFactory::NewEmptyArray(bool weak) } JSHandle ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedValue initVal, bool nonMovable) -{ - if (nonMovable) { - return NewTaggedArray(length, initVal, MemSpaceType::NON_MOVABLE); - } - return NewTaggedArray(length, initVal, MemSpaceType::SEMI_SPACE); -} - -JSHandle ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedValue initVal, MemSpaceType spaceType) { NewObjectHook(); if (length == 0) { @@ -1602,18 +1593,10 @@ JSHandle ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedVal size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length); TaggedObject *header = nullptr; - switch (spaceType) { - case MemSpaceType::SEMI_SPACE: - header = heapHelper_.AllocateYoungGenerationOrHugeObject(arrayClass_, size); - break; - case MemSpaceType::OLD_SPACE: - header = heapHelper_.AllocateOldGenerationOrHugeObject(arrayClass_, size); - break; - case MemSpaceType::NON_MOVABLE: - header = heapHelper_.AllocateNonMovableOrHugeObject(arrayClass_, size); - break; - default: - UNREACHABLE(); + if (nonMovable) { + header = heapHelper_.AllocateNonMovableOrHugeObject(arrayClass_, size); + } else { + header = heapHelper_.AllocateYoungGenerationOrHugeObject(arrayClass_, size); } JSHandle array(thread_, header); @@ -1894,7 +1877,7 @@ EcmaString *ObjectFactory::GetRawStringFromStringTable(const uint8_t *mutf8Data, return EcmaString::Cast(vm_->GetEcmaStringTable()->GetOrInternString(mutf8Data, utf16Len, true)); } - CVector utf16Data(utf16Len); + PandaVector utf16Data(utf16Len); auto len = utf::ConvertRegionMUtf8ToUtf16(mutf8Data, utf16Data.data(), utf::Mutf8Size(mutf8Data), utf16Len, 0); return EcmaString::Cast(vm_->GetEcmaStringTable()->GetOrInternString(utf16Data.data(), len, false)); } @@ -2180,25 +2163,6 @@ EcmaString *ObjectFactory::ResolveString(uint32_t stringId) return GetRawStringFromStringTable(foundStr.data, foundStr.utf16_length, foundStr.is_ascii); } -uintptr_t ObjectFactory::NewSpaceBySnapShotAllocator(size_t size) -{ - NewObjectHook(); - return heapHelper_.AllocateSnapShotSpace(size); -} - -JSHandle ObjectFactory::NewMachineCodeObject(size_t length, const uint8_t *data) -{ - NewObjectHook(); - TaggedObject *obj = heapHelper_.AllocateMachineCodeSpaceObject(machineCodeClass_, length + MachineCode::SIZE); - MachineCode *code = MachineCode::Cast(obj); - code->SetInstructionSizeInBytes(thread_, JSTaggedValue(static_cast(length))); - if (data != nullptr) { - code->SetData(data, length); - } - JSHandle codeObj(thread_, code); - return codeObj; -} - JSHandle ObjectFactory::NewClassInfoExtractor(JSMethod *ctorMethod) { NewObjectHook(); @@ -2219,14 +2183,14 @@ JSHandle ObjectFactory::NewClassInfoExtractor(JSMethod *ctor } // ----------------------------------- new string ---------------------------------------- -JSHandle ObjectFactory::NewFromString(const CString &data) +JSHandle ObjectFactory::NewFromString(const PandaString &data) { auto utf8Data = reinterpret_cast(data.c_str()); bool canBeCompress = EcmaString::CanBeCompressed(utf8Data, data.length()); return GetStringFromStringTable(utf8Data, data.length(), canBeCompress); } -JSHandle ObjectFactory::NewFromCanBeCompressString(const CString &data) +JSHandle ObjectFactory::NewFromCanBeCompressString(const PandaString &data) { auto utf8Data = reinterpret_cast(data.c_str()); ASSERT(EcmaString::CanBeCompressed(utf8Data, data.length())); diff --git a/runtime/object_factory.h b/runtime/object_factory.h index ae3cbe158923b562581469a258d87f970e20e808..01f1dfd16cc662d3ee14cbe4a5ca0ca4da1204c4 100644 --- a/runtime/object_factory.h +++ b/runtime/object_factory.h @@ -26,7 +26,6 @@ #include "plugins/ecmascript/runtime/js_tagged_value.h" #include "plugins/ecmascript/runtime/mem/machine_code.h" #include "plugins/ecmascript/runtime/mem/mem_manager.h" -#include "plugins/ecmascript/runtime/mem/region_factory.h" #include "plugins/ecmascript/runtime/object_wrapper.h" #include "plugins/ecmascript/runtime/tagged_array.h" @@ -82,7 +81,6 @@ class JSLocale; class ResolvingFunctionsRecord; class JSFunctionExtraInfo; class EcmaVM; -class Heap; class ConstantPool; class Program; class EcmaModule; @@ -114,7 +112,7 @@ using DeleteEntryPoint = void (*)(void *, void *); enum class RemoveSlots { YES, NO }; class ObjectFactory { public: - explicit ObjectFactory(JSThread *thread, Heap *heap); + explicit ObjectFactory(JSThread *thread); JSHandle NewProfileTypeInfo(uint32_t length); JSHandle NewConstantPool(uint32_t capacity); @@ -236,8 +234,8 @@ public: JSHandle NewTaggedArray(uint32_t length, JSTaggedValue initVal = JSTaggedValue::Hole()); JSHandle NewTaggedArray(uint32_t length, JSTaggedValue initVal, bool nonMovable); - JSHandle NewTaggedArray(uint32_t length, JSTaggedValue initVal, MemSpaceType spaceType); JSHandle NewWeakTaggedArray(uint32_t length, JSTaggedValue initVal = JSTaggedValue::Hole()); + JSHandle NewDictionaryArray(uint32_t length); JSHandle NewJSForinIterator(const JSHandle &obj); @@ -353,15 +351,13 @@ public: JSHandle NewJSObjectByConstructor(const JSHandle &constructor, const JSHandle &newTarget); - uintptr_t NewSpaceBySnapShotAllocator(size_t size); - JSHandle NewMachineCodeObject(size_t length, const uint8_t *data); JSHandle NewClassInfoExtractor(JSMethod *ctorMethod); ~ObjectFactory() = default; // ----------------------------------- new string ---------------------------------------- - JSHandle NewFromString(const CString &data); - JSHandle NewFromCanBeCompressString(const CString &data); + JSHandle NewFromString(const PandaString &data); + JSHandle NewFromCanBeCompressString(const PandaString &data); JSHandle NewFromStdString(const std::string &data); JSHandle NewFromStdStringUnCheck(const std::string &data, bool canBeCompress); @@ -457,7 +453,6 @@ private: JSHClass *weakLinkedHashSetClass_ {nullptr}; EcmaVM *vm_ {nullptr}; - Heap *heap_ {nullptr}; NO_COPY_SEMANTIC(ObjectFactory); NO_MOVE_SEMANTIC(ObjectFactory); @@ -511,11 +506,5 @@ private: friend class ClassInfoExtractor; friend class DynamicObjectHelpersTest; }; - -class ClassLinkerFactory { -private: - friend class GlobalEnv; // root class in class_linker need dynclass - friend class EcmaVM; // root class in class_linker need dynclass -}; } // namespace panda::ecmascript #endif // ECMASCRIPT_OBJECT_FACTORY_H diff --git a/runtime/object_operator.cpp b/runtime/object_operator.cpp index d8fc375bea62ff264ad178b1d1e8d541d27ad2a1..42fcbc14dd668a3c8efbcdd7e358dd9864658a41 100644 --- a/runtime/object_operator.cpp +++ b/runtime/object_operator.cpp @@ -25,7 +25,7 @@ #include "plugins/ecmascript/runtime/js_hclass-inl.h" #include "plugins/ecmascript/runtime/js_object-inl.h" #include "plugins/ecmascript/runtime/js_primitive_ref.h" -#include "plugins/ecmascript/runtime/mem/c_string.h" +#include "plugins/ecmascript/runtime/mem/ecma_string.h" #include "plugins/ecmascript/runtime/object_factory.h" #include "plugins/ecmascript/runtime/tagged_dictionary.h" #include "plugins/ecmascript/runtime/global_dictionary.h" @@ -200,7 +200,6 @@ void ObjectOperator::FastAdd(JSThread *thread, const JSTaggedValue &receiver, co void ObjectOperator::ToPropertyDescriptor(PropertyDescriptor &desc) const { - DISALLOW_GARBAGE_COLLECTION; if (!IsFound()) { return; } @@ -620,7 +619,6 @@ void ObjectOperator::LookupElementInlinedProps(const JSHandle &obj) } } { - DISALLOW_GARBAGE_COLLECTION; TaggedArray *elements = TaggedArray::Cast(obj->GetElements().GetTaggedObject()); if (elements->GetLength() == 0) { return; // Empty Array diff --git a/runtime/platform/platform.cpp b/runtime/platform/platform.cpp deleted file mode 100644 index e226a1f5654ca6c35575a2488c43fbc5f58b1a1f..0000000000000000000000000000000000000000 --- a/runtime/platform/platform.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/platform/platform.h" - -#include "sys/sysinfo.h" - -namespace panda::ecmascript { -void Platform::Initialize(int threadNum) -{ - os::memory::LockHolder lock(mutex_); - if (isInitialized_++ <= 0) { - runner_ = std::make_unique(TheMostSuitableThreadNum(threadNum)); - } -} - -void Platform::Destroy() -{ - os::memory::LockHolder lock(mutex_); - if (isInitialized_ <= 0) { - return; - } - isInitialized_--; - if (isInitialized_ == 0) { - runner_->TerminateThread(); - } else { - runner_->TerminateTask(); - } -} - -uint32_t Platform::TheMostSuitableThreadNum(uint32_t threadNum) const -{ - if (threadNum > 0) { - return std::min(threadNum, MAX_PLATFORM_THREAD_NUM); - } - uint32_t numOfCpuCore = get_nprocs() - 1; - return std::min(numOfCpuCore, MAX_PLATFORM_THREAD_NUM); -} -} // namespace panda::ecmascript diff --git a/runtime/platform/platform.h b/runtime/platform/platform.h deleted file mode 100644 index 2a4f2b54ad00e891d0b9635bb854507f45bd55b6..0000000000000000000000000000000000000000 --- a/runtime/platform/platform.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_PALTFORM_PLATFORM_H -#define ECMASCRIPT_PALTFORM_PLATFORM_H - -#include - -#include "plugins/ecmascript/runtime/platform/runner.h" -#include "os/mutex.h" - -namespace panda::ecmascript { -class Platform { -public: - static Platform *GetCurrentPlatform() - { - static Platform platform; - return &platform; - } - - Platform() = default; - ~Platform() - { - os::memory::LockHolder lock(mutex_); - runner_->TerminateThread(); - isInitialized_ = 0; - } - - NO_COPY_SEMANTIC(Platform); - NO_MOVE_SEMANTIC(Platform); - - void Initialize(int threadNum = DEFAULT_PLATFORM_THREAD_NUM); - void Destroy(); - - void PostTask(std::unique_ptr task) const - { - ASSERT(isInitialized_ > 0); - runner_->PostTask(std::move(task)); - } - - uint32_t GetTotalThreadNum() const - { - return runner_->GetTotalThreadNum(); - } - - bool IsInThreadPool(std::thread::id id) const - { - return runner_->IsInThreadPool(id); - } - -private: - uint32_t TheMostSuitableThreadNum(uint32_t threadNum) const; - - std::unique_ptr runner_; - int isInitialized_ = 0; - os::memory::Mutex mutex_; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_PALTFORM_PLATFORM_H diff --git a/runtime/platform/runner.cpp b/runtime/platform/runner.cpp deleted file mode 100644 index a70f59a9fbffeca4a18adfca4e3f0cdb905cbac6..0000000000000000000000000000000000000000 --- a/runtime/platform/runner.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/platform/runner.h" - -#include "os/thread.h" - -namespace panda::ecmascript { -Runner::Runner(uint32_t threadNum) : totalThreadNum_(threadNum) -{ - for (uint32_t i = 0; i < threadNum; i++) { - // main thread is 0; - std::unique_ptr thread = std::make_unique(&Runner::Run, this, i + 1); - os::thread::SetThreadName(thread->native_handle(), "GC_WorkerThread"); - threadPool_.emplace_back(std::move(thread)); - } - - for (auto ¤t : runningTask_) { - current = nullptr; - } -} - -void Runner::TerminateTask() -{ - for (auto ¤t : runningTask_) { - auto val = current.load(); - if (val != nullptr) { - val->Terminated(); - } - } -} - -void Runner::TerminateThread() -{ - taskQueue_.Terminate(); - TerminateTask(); - - int threadNum = threadPool_.size(); - for (int i = 0; i < threadNum; i++) { - threadPool_.at(i)->join(); - } - threadPool_.clear(); -} - -void Runner::Run(uint32_t threadId) -{ - while (std::unique_ptr task = taskQueue_.PopTask()) { - runningTask_[threadId].store(task.get()); - task->Run(threadId); - runningTask_[threadId].store(nullptr); - } -} -} // namespace panda::ecmascript diff --git a/runtime/platform/runner.h b/runtime/platform/runner.h deleted file mode 100644 index f5d5cca577628ae1a3f3e0a452f47062e4dd81b7..0000000000000000000000000000000000000000 --- a/runtime/platform/runner.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_PLATFORM_RUNNER_H -#define ECMASCRIPT_PLATFORM_RUNNER_H - -#include -#include -#include - -#include "plugins/ecmascript/runtime/platform/task_queue.h" -#include "libpandabase/os/thread.h" - -namespace panda::ecmascript { -static constexpr uint32_t MAX_PLATFORM_THREAD_NUM = 7; -static constexpr uint32_t DEFAULT_PLATFORM_THREAD_NUM = 0; - -class Runner { -public: - explicit Runner(uint32_t threadNum); - ~Runner() = default; - - NO_COPY_SEMANTIC(Runner); - NO_MOVE_SEMANTIC(Runner); - - void PostTask(std::unique_ptr task) - { - taskQueue_.PostTask(std::move(task)); - } - - void TerminateThread(); - void TerminateTask(); - - uint32_t GetTotalThreadNum() const - { - return totalThreadNum_; - } - - bool IsInThreadPool(std::thread::id id) const - { - for (auto &thread : threadPool_) { - if (thread->get_id() == id) { - return true; - } - } - return false; - } - -private: - void Run(uint32_t threadId); - - std::vector> threadPool_ {}; - TaskQueue taskQueue_ {}; - std::array, MAX_PLATFORM_THREAD_NUM + 1> runningTask_ {}; - uint32_t totalThreadNum_ {0}; - std::vector threadIdToIndexList_; -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_PLATFORM_RUNNER_H diff --git a/runtime/platform/task.h b/runtime/platform/task.h deleted file mode 100644 index 254eace7135ef4e48e789e4c7491cb6776b875d1..0000000000000000000000000000000000000000 --- a/runtime/platform/task.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_PLATFORM_TASK_H -#define ECMASCRIPT_PLATFORM_TASK_H - -#include - -#include "macros.h" - -namespace panda::ecmascript { -class Task { -public: - Task() = default; - virtual ~Task() = default; - virtual bool Run(uint32_t threadIndex) = 0; - - NO_COPY_SEMANTIC(Task); - NO_MOVE_SEMANTIC(Task); - - void Terminated() - { - terminate_.store(true); - } - - bool IsTerminate() - { - return terminate_.load(); - } - -private: - std::atomic terminate_ {false}; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_PLATFORM_TASK_H diff --git a/runtime/platform/task_queue.cpp b/runtime/platform/task_queue.cpp deleted file mode 100644 index 38b73628329dce43a4c3dc9d093c2d44b7147c36..0000000000000000000000000000000000000000 --- a/runtime/platform/task_queue.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/platform/task_queue.h" - -namespace panda::ecmascript { -void TaskQueue::PostTask(std::unique_ptr task) -{ - os::memory::LockHolder holder(mtx_); - ASSERT(!terminate_); - tasks_.push(std::move(task)); - cv_.Signal(); -} - -std::unique_ptr TaskQueue::PopTask() -{ - os::memory::LockHolder holder(mtx_); - while (true) { - if (!tasks_.empty()) { - std::unique_ptr task = std::move(tasks_.front()); - tasks_.pop(); - return task; - } - if (terminate_) { - cv_.SignalAll(); - return nullptr; - } - cv_.Wait(&mtx_); - } -} - -void TaskQueue::Terminate() -{ - os::memory::LockHolder holder(mtx_); - terminate_ = true; - cv_.SignalAll(); -} -} // namespace panda::ecmascript diff --git a/runtime/platform/task_queue.h b/runtime/platform/task_queue.h deleted file mode 100644 index 2285246a88e4aaaa392037966d9dba39b5e86573..0000000000000000000000000000000000000000 --- a/runtime/platform/task_queue.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_PLATFORM_TASK_QUEUE_H -#define ECMASCRIPT_PLATFORM_TASK_QUEUE_H - -#include -#include -#include -#include - -#include "plugins/ecmascript/runtime/platform/task.h" -#include "os/mutex.h" - -namespace panda::ecmascript { -class TaskQueue { -public: - TaskQueue() = default; - ~TaskQueue() = default; - - NO_COPY_SEMANTIC(TaskQueue); - NO_MOVE_SEMANTIC(TaskQueue); - - void PostTask(std::unique_ptr task); - std::unique_ptr PopTask(); - - void Terminate(); - -private: - std::queue> tasks_; - - std::atomic_bool terminate_ = false; - os::memory::Mutex mtx_; - os::memory::ConditionVariable cv_; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_PLATFORM_TASK_QUEUE_H diff --git a/runtime/regexp/dyn_chunk.cpp b/runtime/regexp/dyn_chunk.cpp index 3b415b9bf1f8be24891a894d1dc2d27356bf5347..ab04b98b82d5cd547914c147bcfd705dcc0c1fff 100644 --- a/runtime/regexp/dyn_chunk.cpp +++ b/runtime/regexp/dyn_chunk.cpp @@ -14,6 +14,7 @@ */ #include "plugins/ecmascript/runtime/regexp/dyn_chunk.h" +#include "runtime/include/runtime.h" #include "securec.h" namespace panda::ecmascript { @@ -29,7 +30,8 @@ int DynChunk::Expand(size_t newSize) newSize = size; } newSize = std::max(newSize, ALLOCATE_MIN_SIZE); - auto *newBuf = chunk_->NewArray(newSize); + // NOLINTNEXTLINE(modernize-avoid-c-arrays) + auto *newBuf = Runtime::GetCurrent()->GetInternalAllocator()->New(newSize); if (newBuf == nullptr) { error_ = true; return FAILURE; @@ -44,6 +46,7 @@ int DynChunk::Expand(size_t newSize) return FAILURE; } } + Runtime::GetCurrent()->GetInternalAllocator()->DeleteArray(buf_); buf_ = newBuf; allocatedSize_ = newSize; } diff --git a/runtime/regexp/dyn_chunk.h b/runtime/regexp/dyn_chunk.h index 61646def712be2e2306263fe4751a8e6c8278a9b..2c689982eeea54263cd6a29265124f8c1c7ace30 100644 --- a/runtime/regexp/dyn_chunk.h +++ b/runtime/regexp/dyn_chunk.h @@ -20,7 +20,6 @@ #include "plugins/ecmascript/runtime/ecma_macros.h" #include "plugins/ecmascript/runtime/ecma_vm.h" #include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/chunk.h" namespace panda::ecmascript { class DynChunk { @@ -28,12 +27,15 @@ public: static constexpr size_t ALLOCATE_MIN_SIZE = 64; static constexpr int FAILURE = -1; static constexpr int SUCCESS = 0; - explicit DynChunk(Chunk *chunk) : chunk_(chunk) - { - ASSERT(chunk_ != nullptr); - }; - ~DynChunk() = default; + explicit DynChunk() = default; + + ~DynChunk() + { + if (!isInternalBuffer_) { + Runtime::GetCurrent()->GetInternalAllocator()->DeleteArray(buf_); + } + } NO_COPY_SEMANTIC(DynChunk); NO_MOVE_SEMANTIC(DynChunk); @@ -135,16 +137,13 @@ private: friend class RegExpOpCode; friend class RegExpExecutor; - DynChunk(uint8_t *buf, Chunk *chunk) : buf_(buf), chunk_(chunk) - { - ASSERT(chunk_ != nullptr); - }; + explicit DynChunk(uint8_t *buf) : buf_(buf), isInternalBuffer_(true) {}; uint8_t *buf_ {nullptr}; + bool isInternalBuffer_ {false}; size_t size_ {0}; size_t allocatedSize_ {0}; bool error_ {false}; - Chunk *chunk_ {nullptr}; }; } // namespace panda::ecmascript #endif // ECMASCRIPT_REGEXP_DYN_BUFFER_H diff --git a/runtime/regexp/regexp_executor.cpp b/runtime/regexp/regexp_executor.cpp index 292c0194895c51af2efb5f04c7979e70c665c24e..8e550cc5812c14723d313435e64ed7406a6c6a38 100644 --- a/runtime/regexp/regexp_executor.cpp +++ b/runtime/regexp/regexp_executor.cpp @@ -25,7 +25,7 @@ using RegExpState = RegExpExecutor::RegExpState; using MatchResult = RegExpExecutor::MatchResult; bool RegExpExecutor::Execute(const uint8_t *input, uint32_t lastIndex, uint32_t length, uint8_t *buf, bool isWideChar) { - DynChunk buffer(buf, chunk_); + DynChunk buffer(buf); input_ = const_cast(input); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) inputEnd_ = const_cast(input + length * (isWideChar ? WIDE_CHAR_SIZE : CHAR_SIZE)); @@ -40,15 +40,21 @@ bool RegExpExecutor::Execute(const uint8_t *input, uint32_t lastIndex, uint32_t stateSize_ = sizeof(RegExpState) + captureResultSize + stackSize; stateStackLen_ = 0; + auto allocator = Runtime::GetCurrent()->GetInternalAllocator(); + if (captureResultSize != 0) { - captureResultList_ = chunk_->NewArray(nCapture_); + allocator->DeleteArray(captureResultList_); + // NOLINTNEXTLINE(modernize-avoid-c-arrays) + captureResultList_ = allocator->New(nCapture_); if (memset_s(captureResultList_, captureResultSize, 0, captureResultSize) != EOK) { LOG_ECMA(FATAL) << "memset_s failed"; UNREACHABLE(); } } if (stackSize != 0) { - stack_ = chunk_->NewArray(nStack_); + allocator->DeleteArray(stack_); + // NOLINTNEXTLINE(modernize-avoid-c-arrays) + stack_ = allocator->New(nStack_); if (memset_s(stack_, stackSize, 0, stackSize) != EOK) { LOG_ECMA(FATAL) << "memset_s failed"; UNREACHABLE(); @@ -591,7 +597,8 @@ void RegExpExecutor::DumpResult(std::ostream &out) const CaptureState *captureState = &captureResultList_[i]; int32_t len = captureState->captureEnd - captureState->captureStart; if ((captureState->captureStart != nullptr && captureState->captureEnd != nullptr) && (len >= 0)) { - out << i << ":\t" << CString(reinterpret_cast(captureState->captureStart), len) << std::endl; + out << i << ":\t" << PandaString(reinterpret_cast(captureState->captureStart), len) + << std::endl; } else { out << i << ":\t" << "undefined" << std::endl; @@ -625,7 +632,7 @@ MatchResult RegExpExecutor::GetResult(const JSThread *thread, bool isSuccess) co reinterpret_cast(captureState->captureStart), len / 2, false); } else { // create utf-8 string - CVector buffer(len + 1); + PandaVector buffer(len + 1); uint8_t *dest = buffer.data(); if (memcpy_s(dest, len + 1, reinterpret_cast(captureState->captureStart), len) != EOK) { @@ -710,10 +717,12 @@ RegExpState *RegExpExecutor::PopRegExpState(bool copyCaptrue) void RegExpExecutor::ReAllocStack(uint32_t stackLen) { + auto allocator = Runtime::GetCurrent()->GetInternalAllocator(); if (stackLen > stateStackSize_) { uint32_t newStackSize = std::max(stateStackSize_ * 2, MIN_STACK_SIZE); // 2: double the size uint32_t stackByteSize = newStackSize * stateSize_; - auto newStack = chunk_->NewArray(stackByteSize); + // NOLINTNEXTLINE(modernize-avoid-c-arrays) + auto newStack = allocator->New(stackByteSize); if (memset_s(newStack, stackByteSize, 0, stackByteSize) != EOK) { LOG_ECMA(FATAL) << "memset_s failed"; UNREACHABLE(); @@ -724,6 +733,7 @@ void RegExpExecutor::ReAllocStack(uint32_t stackLen) return; } } + allocator->DeleteArray(stateStack_); stateStack_ = newStack; stateStackSize_ = newStackSize; } diff --git a/runtime/regexp/regexp_executor.h b/runtime/regexp/regexp_executor.h index bc5923343cf092de719542de6f8cdebb090cee7b..a3c89828333f313b72bb85acaec16c1490a23f7f 100644 --- a/runtime/regexp/regexp_executor.h +++ b/runtime/regexp/regexp_executor.h @@ -17,7 +17,6 @@ #define ECMASCRIPT_REGEXP_REGEXP_EXECUTOR_H #include "plugins/ecmascript/runtime/regexp/regexp_parser.h" -#include "plugins/ecmascript/runtime/mem/chunk.h" namespace panda::ecmascript { class RegExpExecutor { @@ -49,12 +48,15 @@ public: bool isSuccess_ = false; }; - explicit RegExpExecutor(Chunk *chunk) : chunk_(chunk) - { - ASSERT(chunk_ != nullptr); - }; + explicit RegExpExecutor() = default; - ~RegExpExecutor() = default; + ~RegExpExecutor() + { + auto allocator = Runtime::GetCurrent()->GetInternalAllocator(); + allocator->DeleteArray(stack_); + allocator->DeleteArray(captureResultList_); + allocator->DeleteArray(stateStack_); + } NO_COPY_SEMANTIC(RegExpExecutor); NO_MOVE_SEMANTIC(RegExpExecutor); @@ -365,7 +367,6 @@ private: uint32_t stateStackSize_ = 0; uint32_t stateSize_ = 0; uint8_t *stateStack_ = nullptr; - Chunk *chunk_ = nullptr; }; } // namespace panda::ecmascript #endif // ECMASCRIPT_REGEXP_REGEXP_EXECUTOR_H diff --git a/runtime/regexp/regexp_parser.cpp b/runtime/regexp/regexp_parser.cpp index e972e9b2ae8b149cb80fc0c180403003c126af95..d08eafac492c53d917a42e096b346a2e314b0bad 100644 --- a/runtime/regexp/regexp_parser.cpp +++ b/runtime/regexp/regexp_parser.cpp @@ -449,7 +449,7 @@ void RegExpParser::ParseAlternative(bool isBackward) } } -int RegExpParser::FindGroupName(const CString &name) +int RegExpParser::FindGroupName(const PandaString &name) { size_t len = 0; size_t nameLen = name.size(); @@ -529,7 +529,7 @@ bool RegExpParser::ParseAssertionCapture(int *captureIndex, bool isBackward) matchAheadOp.InsertOpCode(&buffer_, start, len); } else { Prev(); - CString name; + PandaString name; auto **pp = const_cast(&pc_); if (!ParseGroupSpecifier(pp, name)) { ParseError("GroupName Syntax error."); @@ -756,7 +756,7 @@ void RegExpParser::ParseQuantifier(size_t atomBcStart, int captureStart, int cap } } -bool RegExpParser::ParseGroupSpecifier(const uint8_t **pp, CString &name) +bool RegExpParser::ParseGroupSpecifier(const uint8_t **pp, PandaString &name) { const uint8_t *p = *pp; int c = *p; @@ -784,7 +784,7 @@ int RegExpParser::ParseCaptureCount(const char *groupName) { const uint8_t *p; int captureIndex = 1; - CString name; + PandaString name; for (p = base_; p < end_; p++) { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) switch (*p) { case '(': { diff --git a/runtime/regexp/regexp_parser.h b/runtime/regexp/regexp_parser.h index 6dc705be1cbdfdd33f16d6a1bb14cf493bed0d70..dda9977e2e01f2b338ff1ec15f764f6ce3651d64 100644 --- a/runtime/regexp/regexp_parser.h +++ b/runtime/regexp/regexp_parser.h @@ -19,7 +19,6 @@ #include #include #include -#include "plugins/ecmascript/runtime/mem/chunk.h" #include "plugins/ecmascript/runtime/regexp/dyn_chunk.h" #include "plugins/ecmascript/runtime/regexp/regexp_opcode.h" #include "unicode/stringpiece.h" @@ -51,7 +50,7 @@ public: static constexpr uint32_t UNICODE_HEX_ADVANCE = 2; static constexpr uint32_t CAPTURE_CONUT_ADVANCE = 3; - explicit RegExpParser(Chunk *chunk) : c0_(KEY_EOF), buffer_(chunk), groupNames_(chunk) {} + RegExpParser() = default; ~RegExpParser() { @@ -78,7 +77,7 @@ public: int ParseDecimalDigits(); int ParseAtomEscape(bool isBackward); int ParseCharacterEscape(); - bool ParseGroupSpecifier(const uint8_t **pp, CString &name); + bool ParseGroupSpecifier(const uint8_t **pp, PandaString &name); int ParseCaptureCount(const char *groupName); bool ParseClassRanges(RangeSet *result); void ParseNonemptyClassRangesNoDash(DynChunk *buffer); @@ -86,7 +85,7 @@ public: int ParseClassEscape(RangeSet *atom); void ParseError(const char *errorMessage); void ParseUnicodePropertyValueCharacters(bool *isValue); - int FindGroupName(const CString &name); + int FindGroupName(const PandaString &name); uint32_t ParseOctalLiteral(); bool ParseHexEscape(int length, uint32_t *value); bool ParseUnlimitedLengthHexNumber(uint32_t maxValue, uint32_t *value); @@ -108,12 +107,12 @@ public: return buffer_.size_; } - inline CString GetErrorMsg() const + inline PandaString GetErrorMsg() const { if (isError_) { - return CString(errorMsg_); + return PandaString(errorMsg_); } - return CString(""); + return PandaString(""); } inline bool IsGlobal() const @@ -209,7 +208,7 @@ private: uint8_t *pc_ {nullptr}; uint8_t *end_ {nullptr}; uint32_t flags_ {0}; - int c0_; + int c0_ {KEY_EOF}; int captureCount_ {0}; int stackCount_ {0}; bool isError_ {false}; diff --git a/runtime/runtime_api.h b/runtime/runtime_api.h deleted file mode 100644 index 488618ffe1f15af76c9f692e5745479e7a5ca982..0000000000000000000000000000000000000000 --- a/runtime/runtime_api.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_INTERFACE_RUNTIME_API_H -#define ECMASCRIPT_INTERFACE_RUNTIME_API_H - -#include "plugins/ecmascript/runtime/common.h" -#include "plugins/ecmascript/runtime/mem/parallel_work_helper.h" -#include "plugins/ecmascript/runtime/mem/region.h" -#include "plugins/ecmascript/runtime/mem/remembered_set.h" - -namespace panda::ecmascript { -class WorkerHelper; - -class PUBLIC_API RuntimeApi { -public: - static bool AtomicTestAndSet(RangeBitmap *bitmap, TaggedObject *object); - static void PushWorkList(WorkerHelper *worklist, uint32_t threadId, TaggedObject *object, Region *region); - static void AtomicInsertCrossRegionRememberedSet(RememberedSet *rset, uintptr_t addr); -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_INTERFACE_RUNTIME_API_H diff --git a/runtime/runtime_sources.gn b/runtime/runtime_sources.gn index d1171bc6d4765fbc09eb661052d1225d03a219e9..f7e065bee4572bdb0a593ae28008d2ad02bfdb1e 100644 --- a/runtime/runtime_sources.gn +++ b/runtime/runtime_sources.gn @@ -75,13 +75,6 @@ srcs = [ "generator_helper.cpp", "global_env.cpp", "global_env_constants.cpp", - "hprof/heap_profiler.cpp", - "hprof/heap_profiler_interface.cpp", - "hprof/heap_root_visitor.cpp", - "hprof/heap_snapshot.cpp", - "hprof/heap_snapshot_json_serializer.cpp", - "hprof/heap_tracker.cpp", - "hprof/string_hashmap.cpp", "ic/profile_type_info.cpp", "ic/ic_runtime.cpp", "ic/ic_runtime_stub.cpp", @@ -129,42 +122,18 @@ srcs = [ "literal_data_extractor.cpp", "message_string.cpp", "mem/ecma_reference_processor.cpp", - "mem/c_string.cpp", - "mem/chunk.cpp", - "mem/compress_collector.cpp", - "mem/concurrent_marker.cpp", - "mem/concurrent_sweeper.cpp", + "mem/ecma_string.cpp", "mem/mem_manager.cpp", - "mem/evacuation_allocator.cpp", - "mem/free_object_kind.cpp", - "mem/free_object_list.cpp", - "mem/gc_stats.cpp", - "mem/heap.cpp", - "mem/mem_controller.cpp", - "mem/mix_space_collector.cpp", - "mem/parallel_work_helper.cpp", - "mem/parallel_evacuation.cpp", - "mem/parallel_marker.cpp", - "mem/region_factory.cpp", - "mem/semi_space_collector.cpp", - "mem/space.cpp", - "mem/verification.cpp", "napi/jsnapi.cpp", "napi/jsnapi_debugger_agent.cpp", "object_factory.cpp", "object_operator.cpp", - "platform/platform.cpp", - "platform/runner.cpp", - "platform/task_queue.cpp", "layout_info.cpp", "regexp/dyn_chunk.cpp", "regexp/regexp_executor.cpp", "regexp/regexp_opcode.cpp", "regexp/regexp_parser.cpp", "regexp/regexp_parser_cache.cpp", - "snapshot/mem/slot_bit.cpp", - "snapshot/mem/snapshot.cpp", - "snapshot/mem/snapshot_serialize.cpp", "tagged_dictionary.cpp", "template_string.cpp", "vmstat/caller_stat.cpp", diff --git a/runtime/snapshot/mem/CMakeLists.txt b/runtime/snapshot/mem/CMakeLists.txt deleted file mode 100644 index 041b4d6b91ee17638e3a6ed78e26cd82b0f00697..0000000000000000000000000000000000000000 --- a/runtime/snapshot/mem/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# Huawei Technologies Co.,Ltd. - -cmake_minimum_required(VERSION 3.10) - -set(SNAPSHOT_OUTPUT ${PANDA_BINARY_ROOT}/snapshot) -set(SNAPSHOT_INPUT ${PANDA_ROOT}/runtime/ecmascript/snapshot/strip.native.min.abc) -set(SERIALIZE_ARGUMENTS --load-runtimes=ecmascript --compiler-enable-jit=false --gc-type=epsilon --snapshot-serialize-enabled=true --snapshot-file=${SNAPSHOT_OUTPUT} ${SNAPSHOT_INPUT} _GLOBAL::func_main_0) -set(DESERIALIZE_ARGUMENTS --load-runtimes=ecmascript --compiler-enable-jit=false --gc-type=epsilon --snapshot-file=${SNAPSHOT_OUTPUT} ${SNAPSHOT_INPUT} _GLOBAL::func_main_0) -if(PANDA_TARGET_64 AND NOT PANDA_TARGET_MOBILE) - #add_custom_target(clearSnapshot ALL COMMAND rm -f ${SNAPSHOT_OUTPUT}) - #add_custom_target(generalSnapshot ALL COMMAND ${PANDA_RUN_PREFIX} $ ${SERIALIZE_ARGUMENTS}) - #add_dependencies(generalSnapshot ark clearSnapshot arkruntime) - #add_custom_target(deserializeSnapshot ALL COMMAND ${PANDA_RUN_PREFIX} $ ${DESERIALIZE_ARGUMENTS}) - #add_dependencies(deserializeSnapshot generalSnapshot) -endif() diff --git a/runtime/snapshot/mem/constants.h b/runtime/snapshot/mem/constants.h deleted file mode 100644 index 9a59371eb0df9c9c138d078d1f0e85fb28454ee6..0000000000000000000000000000000000000000 --- a/runtime/snapshot/mem/constants.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_SNAPSHOT_MEM_CONSTANTS_H -#define ECMASCRIPT_SNAPSHOT_MEM_CONSTANTS_H - -// slot bit -static constexpr int OBJECT_INDEX_BIT_NUMBER = 13; // object index -static constexpr int OBJECT_TO_STRING_FLAG_NUMBER = 1; // 1 : reference to string -static constexpr int OBJECT_IN_CONSTANTS_INDEX_NUMBER = 8; // index -static constexpr int OBJECT_TYPE_BIT_NUMBER = 7; // js_type -static constexpr int OBJECT_SIZE_BIT_NUMBER = 18; // 4M -static constexpr int OBJECT_SPECIAL = 1; // special -static constexpr int IS_REFERENCE_SLOT_BIT_NUMBER = 16; // [0x0000] is reference - -static constexpr int MAX_C_POINTER_INDEX = 1024 * 8 - 1; -static constexpr int MAX_OBJECT_INDEX = 8192; -static constexpr int MAX_OBJECT_SIZE_INDEX = 1024 * 256 - 1; - -// object or space align up -static constexpr size_t PAGE_SIZE_ALIGN_UP = 4096; -static constexpr size_t MAX_UINT_32 = 0xFFFFFFFF; - -// builtins native method encode -// builtins deserialize: nativeMehtods_ + getter/setter; program deserialize: getter/setter + programFunctionMethods -static constexpr size_t PROGRAM_NATIVE_METHOD_BEGIN = 6; - -// address slot size -static constexpr int ADDRESS_SIZE = sizeof(uintptr_t); - -// serialize use constants -static constexpr uint8_t MASK_METHOD_SPACE_BEGIN = 0x7F; -static constexpr int OBJECT_SIZE_EXTEND_PAGE = 512; -static constexpr int NATIVE_METHOD_SIZE = 427; - -static constexpr size_t MANAGED_OBJECT_OFFSET = 16; - -#endif // ECMASCRIPT_SNAPSHOT_MEM_CONSTANTS_H diff --git a/runtime/snapshot/mem/slot_bit.cpp b/runtime/snapshot/mem/slot_bit.cpp deleted file mode 100644 index f1e2661a49315092cd048d9d6dad4fe918e0dfd0..0000000000000000000000000000000000000000 --- a/runtime/snapshot/mem/slot_bit.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/snapshot/mem/slot_bit.h" - -#include "plugins/ecmascript/runtime/js_hclass-inl.h" -#include "plugins/ecmascript/runtime/js_tagged_value.h" - -namespace panda::ecmascript { -/* static */ -uint8_t SerializeHelper::GetObjectType(TaggedObject *objectHeader) -{ - auto hclass = objectHeader->GetClass(); - return static_cast(JSHClass::Cast(hclass)->GetObjectType()); -} - -/* static */ -SlotBit SerializeHelper::AddObjectHeaderToData(TaggedObject *objectHeader, CQueue *queue, - std::unordered_map *data, size_t index) -{ - queue->emplace(objectHeader); - SlotBit slotBits(data->size()); - slotBits.SetObjectInConstantsIndex(index); - data->emplace(ToUintPtr(objectHeader), slotBits); - return slotBits; -} - -void SerializeHelper::AddTaggedObjectRangeToData(ObjectSlot start, ObjectSlot end, CQueue *queue, - std::unordered_map *data) -{ - size_t index = 0; - while (start < end) { - JSTaggedValue object(start.GetTaggedType()); - index++; - start++; - if (object.IsHeapObject()) { - SlotBit slotBit(0); - if (data->find(object.GetRawData()) == data->end()) { - slotBit = AddObjectHeaderToData(object.GetTaggedObject(), queue, data, index); - } - } - } -} -} // namespace panda::ecmascript diff --git a/runtime/snapshot/mem/slot_bit.h b/runtime/snapshot/mem/slot_bit.h deleted file mode 100644 index d7afb901179f762842f29087eb63471865591610..0000000000000000000000000000000000000000 --- a/runtime/snapshot/mem/slot_bit.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_SNAPSHOT_MEM_SLOT_BIT_H -#define ECMASCRIPT_SNAPSHOT_MEM_SLOT_BIT_H - -#include "plugins/ecmascript/runtime/mem/c_containers.h" -#include "plugins/ecmascript/runtime/mem/slots.h" -#include "plugins/ecmascript/runtime/snapshot/mem/constants.h" - -#include "utils/bit_field.h" - -namespace panda::ecmascript { -class SlotBit final { -public: - ~SlotBit() = default; - explicit SlotBit() = delete; - - DEFAULT_COPY_SEMANTIC(SlotBit); - DEFAULT_MOVE_SEMANTIC(SlotBit); - - explicit SlotBit(uint64_t value) : value_(value) {} - - using ObjectIndexBits = BitField; - using ObjectToStringBits = ObjectIndexBits::NextField; - using ObjectInConstantsIndexBits = ObjectToStringBits::NextField; - using ObjectTypeBits = ObjectInConstantsIndexBits::NextField; - using ObjectSizeBits = ObjectTypeBits::NextField; - using ObjectSpecial = ObjectSizeBits::NextField; - using IsReferenceSlotBits = ObjectSpecial::NextField; - - void SetReferenceToString(bool flag) - { - ObjectToStringBits::Set(flag, &value_); - } - - void SetObjectInConstantsIndex(size_t index) - { - ObjectInConstantsIndexBits::Set(index, &value_); - } - - size_t GetObjectInConstantsIndex() const - { - return ObjectInConstantsIndexBits::Decode(value_); - } - - bool IsReferenceToString() const - { - return ObjectToStringBits::Decode(value_); - } - - void SetObjectType(uint8_t object_type) - { - ObjectTypeBits::Set(object_type, &value_); - } - - void SetObjectSize(size_t object_size) - { - ObjectSizeBits::Set(object_size, &value_); - } - - void SetObjectIndex(uint32_t object_index) - { - ObjectIndexBits::Set(object_index, &value_); - } - - uint64_t GetValue() const - { - return value_; - } - - uint32_t GetObjectIndex() const - { - return ObjectIndexBits::Decode(value_); - } - - uint8_t GetObjectType() const - { - return ObjectTypeBits::Decode(value_); - } - - size_t GetObjectSize() const - { - return ObjectSizeBits::Decode(value_); - } - - bool IsReferenceSlot() const - { - return IsReferenceSlotBits::Decode(value_) == 0; - } - - bool IsSpecial() const - { - return ObjectSpecial::Decode(value_); - } - - void SetObjectSpecial() - { - ObjectSpecial::Set(true, &value_); - } - - void ClearObjectSpecialFlag() - { - ObjectSpecial::Set(false, &value_); - } - -private: - uint64_t value_; -}; - -class SerializeHelper final { -public: - static uint8_t GetObjectType(TaggedObject *objectHeader); - - static SlotBit AddObjectHeaderToData(TaggedObject *objectHeader, CQueue *queue, - std::unordered_map *data, size_t index = 0); - static void AddTaggedObjectRangeToData(ObjectSlot start, ObjectSlot end, CQueue *queue, - std::unordered_map *data); -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_SNAPSHOT_MEM_SLOT_BIT_H diff --git a/runtime/snapshot/mem/snapshot.cpp b/runtime/snapshot/mem/snapshot.cpp deleted file mode 100644 index 90bfd23990a7c049723826f10d557e15d541a363..0000000000000000000000000000000000000000 --- a/runtime/snapshot/mem/snapshot.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/snapshot/mem/snapshot.h" - -#include -#include -#include -#include - -#include "plugins/ecmascript/runtime/class_linker/program_object.h" -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/global_env.h" -#include "plugins/ecmascript/runtime/jobs/micro_job_queue.h" -#include "plugins/ecmascript/runtime/js_hclass.h" -#include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" -#include "plugins/ecmascript/runtime/mem/mem_manager.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/object_factory.h" -#include "plugins/ecmascript/runtime/snapshot/mem/snapshot_serialize.h" -#include "libpandabase/mem/mem.h" - -namespace panda::ecmascript { -constexpr uint32_t PANDA_FILE_ALIGNMENT = 4096; - -void SnapShot::MakeSnapShotProgramObject(Program *program, const panda_file::File *pf, const CString &fileName) -{ - std::fstream write; - std::pair filePath = VerifyFilePath(fileName); - if (!filePath.first) { - LOG(ERROR, RUNTIME) << "snapshot file path error"; - return; - } - write.open(filePath.second.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); - if (!write.good()) { - LOG(DEBUG, RUNTIME) << "snapshot open file failed"; - return; - } - - SnapShotSerialize serialize(vm_, true); - - std::unordered_map data; - CQueue objectQueue; - - serialize.RegisterNativeMethod(); - - // handle GlobalEnvConstants - auto constant = const_cast(vm_->GetJSThread()->GlobalConstants()); - constant->VisitRangeSlot([&objectQueue, &data]([[maybe_unused]] Root type, ObjectSlot start, ObjectSlot end) { - SerializeHelper::AddTaggedObjectRangeToData(start, end, &objectQueue, &data); - }); - - vm_->Iterate([&objectQueue, &data]([[maybe_unused]] Root type, ObjectSlot object) { - SerializeHelper::AddObjectHeaderToData(object.GetTaggedObjectHeader(), &objectQueue, &data); - }); - - while (!objectQueue.empty()) { - auto taggedObject = objectQueue.front(); - if (taggedObject == nullptr) { - break; - } - objectQueue.pop(); - - serialize.Serialize(taggedObject, &objectQueue, &data); - } - - serialize.SetProgramSerializeStart(); - - // handle program - if (program != nullptr) { - SerializeHelper::AddObjectHeaderToData(program, &objectQueue, &data); - } - - while (!objectQueue.empty()) { - auto taggedObject = objectQueue.front(); - if (taggedObject == nullptr) { - break; - } - objectQueue.pop(); - serialize.Serialize(taggedObject, &objectQueue, &data); - } - - serialize.SerializePandaFileMethod(); - - auto region = vm_->GetHeap()->GetSnapShotSpace()->GetCurrentRegion(); - region->SetHighWaterMark(vm_->GetFactory()->GetHeapManager().GetSnapShotSpaceAllocator().GetTop()); - - // write to file - SnapShotSpace *space = vm_->GetHeap()->GetSnapShotSpace(); - uint32_t snapshot_size = space->GetRegionCount() * DEFAULT_SNAPSHOT_SPACE_SIZE; - uint32_t panda_file_begin = RoundUp(snapshot_size + sizeof(Header), PANDA_FILE_ALIGNMENT); - Header hdr {snapshot_size, panda_file_begin}; - write.write(reinterpret_cast(&hdr), sizeof(hdr)); - - space->EnumerateRegions([&write](Region *current) { - write.write(reinterpret_cast(current), DEFAULT_SNAPSHOT_SPACE_SIZE); - write.flush(); - }); - space->ReclaimRegions(); - ASSERT(static_cast(write.tellp()) == snapshot_size + sizeof(Header)); - - write.seekp(panda_file_begin); - write.write(reinterpret_cast(pf->GetBase()), pf->GetHeader()->file_size); - write.close(); -} - -std::unique_ptr SnapShot::DeserializeGlobalEnvAndProgram(const CString &fileName) -{ - SnapShotSerialize serialize(vm_, false); - - serialize.GeneratedNativeMethod(); - - std::pair filePath = VerifyFilePath(fileName); - if (!filePath.first) { - LOG(ERROR, RUNTIME) << "snapshot file path error"; - return std::unique_ptr(); - } - - int fd = open(filePath.second.c_str(), O_CLOEXEC); // NOLINT(cppcoreguidelines-pro-type-vararg) - if (UNLIKELY(fd == -1)) { - LOG_ECMA(FATAL) << "open file failed"; - UNREACHABLE(); - } - size_t file_size = lseek(fd, 0, SEEK_END); - auto readFile = ToUintPtr(mmap(nullptr, file_size, PROT_READ, MAP_PRIVATE, fd, 0)); - auto hdr = *ToNativePtr(readFile); - if (hdr.snapshot_size % DEFAULT_SNAPSHOT_SPACE_SIZE != 0) { - LOG_ECMA(FATAL) << "Invalid snapshot file"; - UNREACHABLE(); - } - SnapShotSpace *space = vm_->GetHeap()->GetSnapShotSpace(); - - uintptr_t snapshot_begin = readFile + sizeof(Header); - for (size_t i = 0; i < hdr.snapshot_size / DEFAULT_SNAPSHOT_SPACE_SIZE; i++) { - Region *region = const_cast(vm_->GetHeap()->GetRegionFactory()) - ->AllocateAlignedRegion(space, DEFAULT_SNAPSHOT_SPACE_SIZE); - auto fileRegion = ToNativePtr(snapshot_begin + i * DEFAULT_SNAPSHOT_SPACE_SIZE); - - uint64_t base = region->allocateBase_; - uint64_t begin = (fileRegion->begin_) % DEFAULT_SNAPSHOT_SPACE_SIZE; - uint64_t waterMark = (fileRegion->highWaterMark_) % DEFAULT_SNAPSHOT_SPACE_SIZE; - - if (memcpy_s(region, DEFAULT_SNAPSHOT_SPACE_SIZE, fileRegion, DEFAULT_SNAPSHOT_SPACE_SIZE) != EOK) { - LOG_ECMA(FATAL) << "memcpy_s failed"; - UNREACHABLE(); - } - - // space - region->space_ = space; - // allocate_base_ - region->allocateBase_ = base; - // begin_ - region->begin_ = ToUintPtr(region) + begin; - // end_ - region->end_ = ToUintPtr(region) + DEFAULT_SNAPSHOT_SPACE_SIZE; - // high_water_mark_ - region->highWaterMark_ = ToUintPtr(region) + waterMark; - // prev_ - region->prev_ = nullptr; - // next_ - region->next_ = nullptr; - // mark_bitmap_ - region->markBitmap_ = nullptr; - // cross_region_set_ - region->crossRegionSet_ = nullptr; - // old_to_new_set_ - region->oldToNewSet_ = nullptr; - - space->AddRegion(region); - } - munmap(ToNativePtr(readFile), hdr.panda_file_begin); - uintptr_t panda_file_mem = readFile + hdr.panda_file_begin; - auto pf = - panda_file::File::OpenFromMemory(os::mem::ConstBytePtr(ToNativePtr(panda_file_mem), - file_size - hdr.panda_file_begin, os::mem::MmapDeleter), - fileName); - close(fd); - // redirect object field - serialize.RedirectSlot(pf.get()); - return pf; -} - -size_t SnapShot::AlignUpPageSize(size_t spaceSize) -{ - if (spaceSize % PAGE_SIZE_ALIGN_UP == 0) { - return spaceSize; - } - return PAGE_SIZE_ALIGN_UP * (spaceSize / PAGE_SIZE_ALIGN_UP + 1); -} - -std::pair SnapShot::VerifyFilePath(const CString &filePath) -{ - if (filePath.size() > PATH_MAX) { - return std::make_pair(false, ""); - } - CVector resolvedPath(PATH_MAX); - auto result = realpath(filePath.c_str(), resolvedPath.data()); - if (result == resolvedPath.data() || errno == ENOENT) { - return std::make_pair(true, CString(resolvedPath.data())); - } - return std::make_pair(false, ""); -} -} // namespace panda::ecmascript diff --git a/runtime/snapshot/mem/snapshot.h b/runtime/snapshot/mem/snapshot.h deleted file mode 100644 index 920a2aea9c6618e91f3b924ebf19ab0ff7f85786..0000000000000000000000000000000000000000 --- a/runtime/snapshot/mem/snapshot.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_H -#define ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_H - -#include "libpandabase/macros.h" -#include "libpandafile/file.h" - -#include "plugins/ecmascript/runtime/snapshot/mem/slot_bit.h" -#include "plugins/ecmascript/runtime/mem/c_string.h" - -namespace panda::ecmascript { -class Program; -class EcmaVM; - -class SnapShot final { -public: - explicit SnapShot(EcmaVM *vm) : vm_(vm) {} - ~SnapShot() = default; - - void MakeSnapShotProgramObject(Program *program, const panda_file::File *pf, - const CString &fileName = "./snapshot"); - std::unique_ptr DeserializeGlobalEnvAndProgram(const CString &fileName = "./snapshot"); - -private: - struct Header { - uint32_t snapshot_size; - uint32_t panda_file_begin; - }; - -private: - size_t AlignUpPageSize(size_t spaceSize); - std::pair VerifyFilePath(const CString &filePath); - - NO_MOVE_SEMANTIC(SnapShot); - NO_COPY_SEMANTIC(SnapShot); - - EcmaVM *vm_; -}; -} // namespace panda::ecmascript -#endif // ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_H diff --git a/runtime/snapshot/mem/snapshot_serialize.cpp b/runtime/snapshot/mem/snapshot_serialize.cpp deleted file mode 100644 index 4f07d05d724e58c749afb6178a8bb1a8959400c5..0000000000000000000000000000000000000000 --- a/runtime/snapshot/mem/snapshot_serialize.cpp +++ /dev/null @@ -1,1267 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/snapshot/mem/snapshot_serialize.h" - -#include "plugins/ecmascript/runtime/base/error_type.h" -#include "plugins/ecmascript/runtime/builtins/builtins_array.h" -#include "plugins/ecmascript/runtime/builtins/builtins_arraybuffer.h" -#include "plugins/ecmascript/runtime/builtins/builtins_async_from_sync_iterator.h" -#include "plugins/ecmascript/runtime/builtins/builtins_async_function.h" -#include "plugins/ecmascript/runtime/builtins/builtins_async_generator.h" -#include "plugins/ecmascript/runtime/builtins/builtins_async_iterator.h" -#include "plugins/ecmascript/runtime/builtins/builtins_boolean.h" -#include "plugins/ecmascript/runtime/builtins/builtins_collator.h" -#include "plugins/ecmascript/runtime/builtins/builtins_dataview.h" -#include "plugins/ecmascript/runtime/builtins/builtins_date.h" -#include "plugins/ecmascript/runtime/builtins/builtins_date_time_format.h" -#include "plugins/ecmascript/runtime/builtins/builtins_errors.h" -#include "plugins/ecmascript/runtime/builtins/builtins_function.h" -#include "plugins/ecmascript/runtime/builtins/builtins_generator.h" -#include "plugins/ecmascript/runtime/builtins/builtins_global.h" -#include "plugins/ecmascript/runtime/builtins/builtins_intl.h" -#include "plugins/ecmascript/runtime/builtins/builtins_iterator.h" -#include "plugins/ecmascript/runtime/builtins/builtins_json.h" -#include "plugins/ecmascript/runtime/builtins/builtins_locale.h" -#include "plugins/ecmascript/runtime/builtins/builtins_map.h" -#include "plugins/ecmascript/runtime/builtins/builtins_math.h" -#include "plugins/ecmascript/runtime/builtins/builtins_number.h" -#include "plugins/ecmascript/runtime/builtins/builtins_number_format.h" -#include "plugins/ecmascript/runtime/builtins/builtins_object.h" -#include "plugins/ecmascript/runtime/builtins/builtins_plural_rules.h" -#include "plugins/ecmascript/runtime/builtins/builtins_promise.h" -#include "plugins/ecmascript/runtime/builtins/builtins_promise_handler.h" -#include "plugins/ecmascript/runtime/builtins/builtins_promise_job.h" -#include "plugins/ecmascript/runtime/builtins/builtins_proxy.h" -#include "plugins/ecmascript/runtime/builtins/builtins_reflect.h" -#include "plugins/ecmascript/runtime/builtins/builtins_regexp.h" -#include "plugins/ecmascript/runtime/builtins/builtins_relative_time_format.h" -#include "plugins/ecmascript/runtime/builtins/builtins_set.h" -#include "plugins/ecmascript/runtime/builtins/builtins_string.h" -#include "plugins/ecmascript/runtime/builtins/builtins_string_iterator.h" -#include "plugins/ecmascript/runtime/builtins/builtins_symbol.h" -#include "plugins/ecmascript/runtime/builtins/builtins_typedarray.h" -#include "plugins/ecmascript/runtime/builtins/builtins_weak_map.h" -#include "plugins/ecmascript/runtime/builtins/builtins_weak_set.h" -#include "plugins/ecmascript/runtime/class_linker/program_object.h" -#include "plugins/ecmascript/runtime/containers/containers_arraylist.h" -#include "plugins/ecmascript/runtime/global_env.h" -#include "plugins/ecmascript/runtime/js_array_iterator.h" -#include "plugins/ecmascript/runtime/js_for_in_iterator.h" -#include "plugins/ecmascript/runtime/js_hclass.h" -#include "plugins/ecmascript/runtime/js_map_iterator.h" -#include "plugins/ecmascript/runtime/js_set_iterator.h" -#include "plugins/ecmascript/runtime/js_tagged_value-inl.h" -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/region_factory.h" -#include "plugins/ecmascript/runtime/mem/space-inl.h" -#include "plugins/ecmascript/runtime/object_factory.h" - -namespace panda::ecmascript { -using Number = builtins::BuiltinsNumber; -using Object = builtins::BuiltinsObject; -using Date = builtins::BuiltinsDate; -using Symbol = builtins::BuiltinsSymbol; -using Boolean = builtins::BuiltinsBoolean; -using BuiltinsMap = builtins::BuiltinsMap; -using BuiltinsSet = builtins::BuiltinsSet; -using BuiltinsWeakMap = builtins::BuiltinsWeakMap; -using BuiltinsWeakSet = builtins::BuiltinsWeakSet; -using BuiltinsArray = builtins::BuiltinsArray; -using BuiltinsTypedArray = builtins::BuiltinsTypedArray; -using BuiltinsIterator = builtins::BuiltinsIterator; -using BuiltinsAsyncIterator = builtins::BuiltinsAsyncIterator; -using Error = builtins::BuiltinsError; -using RangeError = builtins::BuiltinsRangeError; -using ReferenceError = builtins::BuiltinsReferenceError; -using TypeError = builtins::BuiltinsTypeError; -using URIError = builtins::BuiltinsURIError; -using SyntaxError = builtins::BuiltinsSyntaxError; -using EvalError = builtins::BuiltinsEvalError; -using ErrorType = base::ErrorType; -using Global = builtins::BuiltinsGlobal; -using BuiltinsString = builtins::BuiltinsString; -using StringIterator = builtins::BuiltinsStringIterator; -using RegExp = builtins::BuiltinsRegExp; -using Function = builtins::BuiltinsFunction; -using Math = builtins::BuiltinsMath; -using ArrayBuffer = builtins::BuiltinsArrayBuffer; -using Json = builtins::BuiltinsJson; -using Proxy = builtins::BuiltinsProxy; -using Reflect = builtins::BuiltinsReflect; -using AsyncFunction = builtins::BuiltinsAsyncFunction; -using AsyncGeneratorObject = builtins::BuiltinsAsyncGenerator; -using AsyncFromSyncIterator = builtins::BuiltinsAsyncFromSyncIterator; -using GeneratorObject = builtins::BuiltinsGenerator; -using Promise = builtins::BuiltinsPromise; -using BuiltinsPromiseHandler = builtins::BuiltinsPromiseHandler; -using BuiltinsPromiseJob = builtins::BuiltinsPromiseJob; -using ErrorType = base::ErrorType; -using DataView = builtins::BuiltinsDataView; -using Intl = builtins::BuiltinsIntl; -using Locale = builtins::BuiltinsLocale; -using DateTimeFormat = builtins::BuiltinsDateTimeFormat; -using NumberFormat = builtins::BuiltinsNumberFormat; -using RelativeTimeFormat = builtins::BuiltinsRelativeTimeFormat; -using Collator = builtins::BuiltinsCollator; -using PluralRules = builtins::BuiltinsPluralRules; -using ArrayList = containers::ContainersArrayList; - -constexpr int TAGGED_SIZE = JSTaggedValue::TaggedTypeSize(); -constexpr int OBJECT_HEADER_SIZE = TaggedObject::TaggedObjectSize(); -constexpr int METHOD_SIZE = sizeof(JSMethod); - -// NOLINTNEXTLINE(modernize-avoid-c-arrays) -static uintptr_t g_nativeTable[] = { - reinterpret_cast(nullptr), - reinterpret_cast(BuiltinsMap::Species), - reinterpret_cast(StringIterator::Next), - reinterpret_cast(Function::FunctionPrototypeInvokeSelf), - reinterpret_cast(Function::FunctionConstructor), - reinterpret_cast(JSFunction::AccessCallerArgumentsThrowTypeError), - reinterpret_cast(Function::FunctionPrototypeApply), - reinterpret_cast(Function::FunctionPrototypeBind), - reinterpret_cast(Function::FunctionPrototypeCall), - reinterpret_cast(Function::FunctionPrototypeToString), - reinterpret_cast(Object::ObjectConstructor), - reinterpret_cast(Error::ErrorConstructor), - reinterpret_cast(Error::ToString), - reinterpret_cast(RangeError::RangeErrorConstructor), - reinterpret_cast(RangeError::ToString), - reinterpret_cast(ReferenceError::ReferenceErrorConstructor), - reinterpret_cast(ReferenceError::ToString), - reinterpret_cast(TypeError::TypeErrorConstructor), - reinterpret_cast(TypeError::ToString), - reinterpret_cast(TypeError::ThrowTypeError), - reinterpret_cast(URIError::URIErrorConstructor), - reinterpret_cast(URIError::ToString), - reinterpret_cast(SyntaxError::SyntaxErrorConstructor), - reinterpret_cast(SyntaxError::ToString), - reinterpret_cast(EvalError::EvalErrorConstructor), - reinterpret_cast(EvalError::ToString), - reinterpret_cast(Number::NumberConstructor), - reinterpret_cast(Number::ToExponential), - reinterpret_cast(Number::ToFixed), - reinterpret_cast(Number::ToLocaleString), - reinterpret_cast(Number::ToPrecision), - reinterpret_cast(Number::ToString), - reinterpret_cast(Number::ValueOf), - reinterpret_cast(Number::IsFinite), - reinterpret_cast(Number::IsInteger), - reinterpret_cast(Number::IsNaN), - reinterpret_cast(Number::IsSafeInteger), - reinterpret_cast(Number::ParseFloat), - reinterpret_cast(Number::ParseInt), - reinterpret_cast(Symbol::SymbolConstructor), - reinterpret_cast(Symbol::For), - reinterpret_cast(Symbol::KeyFor), - reinterpret_cast(Symbol::DescriptionGetter), - reinterpret_cast(Symbol::ToPrimitive), - reinterpret_cast(Symbol::ToString), - reinterpret_cast(Symbol::ValueOf), - reinterpret_cast(Function::FunctionPrototypeHasInstance), - reinterpret_cast(Date::DateConstructor), - reinterpret_cast(Date::GetDate), - reinterpret_cast(Date::GetDay), - reinterpret_cast(Date::GetFullYear), - reinterpret_cast(Date::GetHours), - reinterpret_cast(Date::GetMilliseconds), - reinterpret_cast(Date::GetMinutes), - reinterpret_cast(Date::GetMonth), - reinterpret_cast(Date::GetSeconds), - reinterpret_cast(Date::GetTime), - reinterpret_cast(Date::GetTimezoneOffset), - reinterpret_cast(Date::GetUTCDate), - reinterpret_cast(Date::GetUTCDay), - reinterpret_cast(Date::GetUTCFullYear), - reinterpret_cast(Date::GetUTCHours), - reinterpret_cast(Date::GetUTCMilliseconds), - reinterpret_cast(Date::GetUTCMinutes), - reinterpret_cast(Date::GetUTCMonth), - reinterpret_cast(Date::GetUTCSeconds), - reinterpret_cast(Date::SetDate), - reinterpret_cast(Date::SetFullYear), - reinterpret_cast(Date::SetHours), - reinterpret_cast(Date::SetMilliseconds), - reinterpret_cast(Date::SetMinutes), - reinterpret_cast(Date::SetMonth), - reinterpret_cast(Date::SetSeconds), - reinterpret_cast(Date::SetTime), - reinterpret_cast(Date::SetUTCDate), - reinterpret_cast(Date::SetUTCFullYear), - reinterpret_cast(Date::SetUTCHours), - reinterpret_cast(Date::SetUTCMilliseconds), - reinterpret_cast(Date::SetUTCMinutes), - reinterpret_cast(Date::SetUTCMonth), - reinterpret_cast(Date::SetUTCSeconds), - reinterpret_cast(Date::ToDateString), - reinterpret_cast(Date::ToISOString), - reinterpret_cast(Date::ToJSON), - reinterpret_cast(Date::ToLocaleDateString), - reinterpret_cast(Date::ToLocaleString), - reinterpret_cast(Date::ToLocaleTimeString), - reinterpret_cast(Date::ToString), - reinterpret_cast(Date::ToTimeString), - reinterpret_cast(Date::ToUTCString), - reinterpret_cast(Date::ValueOf), - reinterpret_cast(Date::ToPrimitive), - reinterpret_cast(Date::Now), - reinterpret_cast(Date::Parse), - reinterpret_cast(Date::UTC), - reinterpret_cast(Object::Assign), - reinterpret_cast(Object::Create), - reinterpret_cast(Object::DefineProperties), - reinterpret_cast(Object::DefineProperty), - reinterpret_cast(Object::Freeze), - reinterpret_cast(Object::GetOwnPropertyDesciptor), - reinterpret_cast(Object::GetOwnPropertyNames), - reinterpret_cast(Object::GetOwnPropertySymbols), - reinterpret_cast(Object::GetPrototypeOf), - reinterpret_cast(Object::Is), - reinterpret_cast(Object::IsExtensible), - reinterpret_cast(Object::IsFrozen), - reinterpret_cast(Object::IsSealed), - reinterpret_cast(Object::Keys), - reinterpret_cast(Object::PreventExtensions), - reinterpret_cast(Object::Seal), - reinterpret_cast(Object::SetPrototypeOf), - reinterpret_cast(Object::HasOwnProperty), - reinterpret_cast(Object::IsPrototypeOf), - reinterpret_cast(Object::PropertyIsEnumerable), - reinterpret_cast(Object::ToLocaleString), - reinterpret_cast(Object::ToString), - reinterpret_cast(Object::ValueOf), - reinterpret_cast(Object::ProtoGetter), - reinterpret_cast(Object::ProtoSetter), - reinterpret_cast(Object::DefineGetter), - reinterpret_cast(Object::DefineSetter), - reinterpret_cast(Object::LookupGetter), - reinterpret_cast(Object::LookupSetter), - reinterpret_cast(Object::CreateRealm), - reinterpret_cast(Object::Entries), - reinterpret_cast(Boolean::BooleanConstructor), - reinterpret_cast(Boolean::BooleanPrototypeToString), - reinterpret_cast(Boolean::BooleanPrototypeValueOf), - reinterpret_cast(RegExp::RegExpConstructor), - reinterpret_cast(RegExp::Exec), - reinterpret_cast(RegExp::Test), - reinterpret_cast(RegExp::ToString), - reinterpret_cast(RegExp::GetFlags), - reinterpret_cast(RegExp::GetSource), - reinterpret_cast(RegExp::GetGlobal), - reinterpret_cast(RegExp::GetIgnoreCase), - reinterpret_cast(RegExp::GetMultiline), - reinterpret_cast(RegExp::GetDotAll), - reinterpret_cast(RegExp::GetSticky), - reinterpret_cast(RegExp::GetUnicode), - reinterpret_cast(RegExp::Split), - reinterpret_cast(RegExp::Search), - reinterpret_cast(RegExp::Match), - reinterpret_cast(RegExp::Replace), - reinterpret_cast(BuiltinsSet::SetConstructor), - reinterpret_cast(BuiltinsSet::Add), - reinterpret_cast(BuiltinsSet::Clear), - reinterpret_cast(BuiltinsSet::Delete), - reinterpret_cast(BuiltinsSet::Has), - reinterpret_cast(BuiltinsSet::ForEach), - reinterpret_cast(BuiltinsSet::Entries), - reinterpret_cast(BuiltinsSet::Values), - reinterpret_cast(BuiltinsSet::GetSize), - reinterpret_cast(BuiltinsSet::Species), - reinterpret_cast(BuiltinsMap::MapConstructor), - reinterpret_cast(BuiltinsMap::Set), - reinterpret_cast(BuiltinsMap::Clear), - reinterpret_cast(BuiltinsMap::Delete), - reinterpret_cast(BuiltinsMap::Has), - reinterpret_cast(BuiltinsMap::Get), - reinterpret_cast(BuiltinsMap::ForEach), - reinterpret_cast(BuiltinsMap::Keys), - reinterpret_cast(BuiltinsMap::Values), - reinterpret_cast(BuiltinsMap::Entries), - reinterpret_cast(BuiltinsMap::GetSize), - reinterpret_cast(BuiltinsWeakMap::WeakMapConstructor), - reinterpret_cast(BuiltinsWeakMap::Set), - reinterpret_cast(BuiltinsWeakMap::Delete), - reinterpret_cast(BuiltinsWeakMap::Has), - reinterpret_cast(BuiltinsWeakMap::Get), - reinterpret_cast(BuiltinsWeakSet::WeakSetConstructor), - reinterpret_cast(BuiltinsWeakSet::Add), - reinterpret_cast(BuiltinsWeakSet::Delete), - reinterpret_cast(BuiltinsWeakSet::Has), - reinterpret_cast(BuiltinsArray::ArrayConstructor), - reinterpret_cast(BuiltinsArray::Concat), - reinterpret_cast(BuiltinsArray::CopyWithin), - reinterpret_cast(BuiltinsArray::Entries), - reinterpret_cast(BuiltinsArray::Every), - reinterpret_cast(BuiltinsArray::Fill), - reinterpret_cast(BuiltinsArray::Filter), - reinterpret_cast(BuiltinsArray::Find), - reinterpret_cast(BuiltinsArray::FindIndex), - reinterpret_cast(BuiltinsArray::ForEach), - reinterpret_cast(BuiltinsArray::IndexOf), - reinterpret_cast(BuiltinsArray::Join), - reinterpret_cast(BuiltinsArray::Keys), - reinterpret_cast(BuiltinsArray::LastIndexOf), - reinterpret_cast(BuiltinsArray::Map), - reinterpret_cast(BuiltinsArray::Pop), - reinterpret_cast(BuiltinsArray::Push), - reinterpret_cast(BuiltinsArray::Reduce), - reinterpret_cast(BuiltinsArray::ReduceRight), - reinterpret_cast(BuiltinsArray::Reverse), - reinterpret_cast(BuiltinsArray::Shift), - reinterpret_cast(BuiltinsArray::Slice), - reinterpret_cast(BuiltinsArray::Some), - reinterpret_cast(BuiltinsArray::Sort), - reinterpret_cast(BuiltinsArray::Splice), - reinterpret_cast(BuiltinsArray::ToLocaleString), - reinterpret_cast(BuiltinsArray::ToString), - reinterpret_cast(BuiltinsArray::Unshift), - reinterpret_cast(BuiltinsArray::Values), - reinterpret_cast(BuiltinsArray::From), - reinterpret_cast(BuiltinsArray::IsArray), - reinterpret_cast(BuiltinsArray::Of), - reinterpret_cast(BuiltinsArray::Species), - reinterpret_cast(BuiltinsArray::Unscopables), - reinterpret_cast(BuiltinsTypedArray::TypedArrayBaseConstructor), - reinterpret_cast(BuiltinsTypedArray::CopyWithin), - reinterpret_cast(BuiltinsTypedArray::Entries), - reinterpret_cast(BuiltinsTypedArray::Every), - reinterpret_cast(BuiltinsTypedArray::Fill), - reinterpret_cast(BuiltinsTypedArray::Filter), - reinterpret_cast(BuiltinsTypedArray::Find), - reinterpret_cast(BuiltinsTypedArray::FindIndex), - reinterpret_cast(BuiltinsTypedArray::ForEach), - reinterpret_cast(BuiltinsTypedArray::IndexOf), - reinterpret_cast(BuiltinsTypedArray::Join), - reinterpret_cast(BuiltinsTypedArray::Keys), - reinterpret_cast(BuiltinsTypedArray::LastIndexOf), - reinterpret_cast(BuiltinsTypedArray::Map), - reinterpret_cast(BuiltinsTypedArray::Reduce), - reinterpret_cast(BuiltinsTypedArray::ReduceRight), - reinterpret_cast(BuiltinsTypedArray::Reverse), - reinterpret_cast(BuiltinsTypedArray::Set), - reinterpret_cast(BuiltinsTypedArray::Slice), - reinterpret_cast(BuiltinsTypedArray::Some), - reinterpret_cast(BuiltinsTypedArray::Sort), - reinterpret_cast(BuiltinsTypedArray::Subarray), - reinterpret_cast(BuiltinsTypedArray::ToLocaleString), - reinterpret_cast(BuiltinsTypedArray::Values), - reinterpret_cast(BuiltinsTypedArray::GetBuffer), - reinterpret_cast(BuiltinsTypedArray::GetByteLength), - reinterpret_cast(BuiltinsTypedArray::GetByteOffset), - reinterpret_cast(BuiltinsTypedArray::GetLength), - reinterpret_cast(BuiltinsTypedArray::ToStringTag), - reinterpret_cast(BuiltinsTypedArray::From), - reinterpret_cast(BuiltinsTypedArray::Of), - reinterpret_cast(BuiltinsTypedArray::Species), - reinterpret_cast(BuiltinsTypedArray::Int8ArrayConstructor), - reinterpret_cast(BuiltinsTypedArray::Uint8ArrayConstructor), - reinterpret_cast(BuiltinsTypedArray::Uint8ClampedArrayConstructor), - reinterpret_cast(BuiltinsTypedArray::Int16ArrayConstructor), - reinterpret_cast(BuiltinsTypedArray::Uint16ArrayConstructor), - reinterpret_cast(BuiltinsTypedArray::Int32ArrayConstructor), - reinterpret_cast(BuiltinsTypedArray::Uint32ArrayConstructor), - reinterpret_cast(BuiltinsTypedArray::Float32ArrayConstructor), - reinterpret_cast(BuiltinsTypedArray::Float64ArrayConstructor), - reinterpret_cast(BuiltinsString::StringConstructor), - reinterpret_cast(BuiltinsString::CharAt), - reinterpret_cast(BuiltinsString::CharCodeAt), - reinterpret_cast(BuiltinsString::CodePointAt), - reinterpret_cast(BuiltinsString::Concat), - reinterpret_cast(BuiltinsString::EndsWith), - reinterpret_cast(BuiltinsString::Includes), - reinterpret_cast(BuiltinsString::IndexOf), - reinterpret_cast(BuiltinsString::LastIndexOf), - reinterpret_cast(BuiltinsString::LocaleCompare), - reinterpret_cast(BuiltinsString::Match), - reinterpret_cast(BuiltinsString::Normalize), - reinterpret_cast(BuiltinsString::Repeat), - reinterpret_cast(BuiltinsString::Replace), - reinterpret_cast(BuiltinsString::Search), - reinterpret_cast(BuiltinsString::Slice), - reinterpret_cast(BuiltinsString::Split), - reinterpret_cast(BuiltinsString::StartsWith), - reinterpret_cast(BuiltinsString::Substring), - reinterpret_cast(BuiltinsString::SubStr), - reinterpret_cast(BuiltinsString::ToLocaleLowerCase), - reinterpret_cast(BuiltinsString::ToLocaleUpperCase), - reinterpret_cast(BuiltinsString::ToLowerCase), - reinterpret_cast(BuiltinsString::ToString), - reinterpret_cast(BuiltinsString::ToUpperCase), - reinterpret_cast(BuiltinsString::Trim), - reinterpret_cast(BuiltinsString::ValueOf), - reinterpret_cast(BuiltinsString::GetStringIterator), - reinterpret_cast(BuiltinsString::FromCharCode), - reinterpret_cast(BuiltinsString::FromCodePoint), - reinterpret_cast(BuiltinsString::Raw), - reinterpret_cast(BuiltinsString::GetLength), - reinterpret_cast(ArrayBuffer::ArrayBufferConstructor), - reinterpret_cast(ArrayBuffer::Slice), - reinterpret_cast(ArrayBuffer::IsView), - reinterpret_cast(ArrayBuffer::Species), - reinterpret_cast(ArrayBuffer::GetByteLength), - reinterpret_cast(DataView::DataViewConstructor), - reinterpret_cast(DataView::GetFloat32), - reinterpret_cast(DataView::GetFloat64), - reinterpret_cast(DataView::GetInt8), - reinterpret_cast(DataView::GetInt16), - reinterpret_cast(DataView::GetInt32), - reinterpret_cast(DataView::GetUint8), - reinterpret_cast(DataView::GetUint16), - reinterpret_cast(DataView::GetUint32), - reinterpret_cast(DataView::SetFloat32), - reinterpret_cast(DataView::SetFloat64), - reinterpret_cast(DataView::SetInt8), - reinterpret_cast(DataView::SetInt16), - reinterpret_cast(DataView::SetInt32), - reinterpret_cast(DataView::SetUint8), - reinterpret_cast(DataView::SetUint16), - reinterpret_cast(DataView::SetUint32), - reinterpret_cast(DataView::GetBuffer), - reinterpret_cast(DataView::GetByteLength), - reinterpret_cast(DataView::GetOffset), - reinterpret_cast(Global::PrintEntrypoint), - reinterpret_cast(Global::GcEntrypoint), - reinterpret_cast(Global::NotSupportEval), - reinterpret_cast(Global::IsFinite), - reinterpret_cast(Global::IsNaN), - reinterpret_cast(Global::DecodeURI), - reinterpret_cast(Global::DecodeURIComponent), - reinterpret_cast(Global::EncodeURI), - reinterpret_cast(Global::EncodeURIComponent), - reinterpret_cast(Math::Abs), - reinterpret_cast(Math::Acos), - reinterpret_cast(Math::Acosh), - reinterpret_cast(Math::Asin), - reinterpret_cast(Math::Asinh), - reinterpret_cast(Math::Atan), - reinterpret_cast(Math::Atanh), - reinterpret_cast(Math::Atan2), - reinterpret_cast(Math::Cbrt), - reinterpret_cast(Math::Ceil), - reinterpret_cast(Math::Clz32), - reinterpret_cast(Math::Cos), - reinterpret_cast(Math::Cosh), - reinterpret_cast(Math::Exp), - reinterpret_cast(Math::Expm1), - reinterpret_cast(Math::Floor), - reinterpret_cast(Math::Fround), - reinterpret_cast(Math::Hypot), - reinterpret_cast(Math::Imul), - reinterpret_cast(Math::Log), - reinterpret_cast(Math::Log1p), - reinterpret_cast(Math::Log10), - reinterpret_cast(Math::Log2), - reinterpret_cast(Math::Max), - reinterpret_cast(Math::Min), - reinterpret_cast(Math::Pow), - reinterpret_cast(Math::Random), - reinterpret_cast(Math::Round), - reinterpret_cast(Math::Sign), - reinterpret_cast(Math::Sin), - reinterpret_cast(Math::Sinh), - reinterpret_cast(Math::Sqrt), - reinterpret_cast(Math::Tan), - reinterpret_cast(Math::Tanh), - reinterpret_cast(Math::Trunc), - reinterpret_cast(Json::Parse), - reinterpret_cast(Json::Stringify), - reinterpret_cast(BuiltinsIterator::Next), - reinterpret_cast(BuiltinsIterator::Return), - reinterpret_cast(BuiltinsIterator::Throw), - reinterpret_cast(BuiltinsIterator::GetIteratorObj), - reinterpret_cast(BuiltinsAsyncIterator::GetAsyncIteratorObj), - reinterpret_cast(JSForInIterator::Next), - reinterpret_cast(JSSetIterator::Next), - reinterpret_cast(JSMapIterator::Next), - reinterpret_cast(JSArrayIterator::Next), - reinterpret_cast(Proxy::ProxyConstructor), - reinterpret_cast(Proxy::Revocable), - reinterpret_cast(Reflect::ReflectApply), - reinterpret_cast(Reflect::ReflectConstruct), - reinterpret_cast(Reflect::ReflectDefineProperty), - reinterpret_cast(Reflect::ReflectDeleteProperty), - reinterpret_cast(Reflect::ReflectGet), - reinterpret_cast(Reflect::ReflectGetOwnPropertyDescriptor), - reinterpret_cast(Reflect::ReflectGetPrototypeOf), - reinterpret_cast(Reflect::ReflectHas), - reinterpret_cast(Reflect::ReflectIsExtensible), - reinterpret_cast(Reflect::ReflectOwnKeys), - reinterpret_cast(Reflect::ReflectPreventExtensions), - reinterpret_cast(Reflect::ReflectSet), - reinterpret_cast(Reflect::ReflectSetPrototypeOf), - reinterpret_cast(AsyncFunction::AsyncFunctionConstructor), - reinterpret_cast(AsyncGeneratorObject::AsyncGeneratorPrototypeNext), - reinterpret_cast(AsyncGeneratorObject::AsyncGeneratorPrototypeReturn), - reinterpret_cast(AsyncGeneratorObject::AsyncGeneratorPrototypeThrow), - reinterpret_cast(AsyncGeneratorObject::AsyncGeneratorFunctionConstructor), - reinterpret_cast(AsyncFromSyncIterator::AsyncFromSyncIteratorPrototypeNext), - reinterpret_cast(AsyncFromSyncIterator::AsyncFromSyncIteratorPrototypeReturn), - reinterpret_cast(AsyncFromSyncIterator::AsyncFromSyncIteratorPrototypeThrow), - reinterpret_cast(GeneratorObject::GeneratorPrototypeNext), - reinterpret_cast(GeneratorObject::GeneratorPrototypeReturn), - reinterpret_cast(GeneratorObject::GeneratorPrototypeThrow), - reinterpret_cast(GeneratorObject::GeneratorFunctionConstructor), - reinterpret_cast(Promise::PromiseConstructor), - reinterpret_cast(Promise::All), - reinterpret_cast(Promise::Race), - reinterpret_cast(Promise::Resolve), - reinterpret_cast(Promise::Reject), - reinterpret_cast(Promise::Catch), - reinterpret_cast(Promise::Then), - reinterpret_cast(Promise::GetSpecies), - reinterpret_cast(BuiltinsPromiseJob::PromiseReactionJob), - reinterpret_cast(BuiltinsPromiseJob::PromiseResolveThenableJob), - reinterpret_cast(Intl::GetCanonicalLocales), - reinterpret_cast(Locale::LocaleConstructor), - reinterpret_cast(Locale::Maximize), - reinterpret_cast(Locale::Minimize), - reinterpret_cast(Locale::ToString), - reinterpret_cast(Locale::GetBaseName), - reinterpret_cast(Locale::GetCalendar), - reinterpret_cast(Locale::GetCaseFirst), - reinterpret_cast(Locale::GetCollation), - reinterpret_cast(Locale::GetHourCycle), - reinterpret_cast(Locale::GetNumeric), - reinterpret_cast(Locale::GetNumberingSystem), - reinterpret_cast(Locale::GetLanguage), - reinterpret_cast(Locale::GetScript), - reinterpret_cast(Locale::GetRegion), - reinterpret_cast(DateTimeFormat::DateTimeFormatConstructor), - reinterpret_cast(DateTimeFormat::SupportedLocalesOf), - reinterpret_cast(DateTimeFormat::Format), - reinterpret_cast(DateTimeFormat::FormatToParts), - reinterpret_cast(DateTimeFormat::ResolvedOptions), - reinterpret_cast(DateTimeFormat::FormatRange), - reinterpret_cast(DateTimeFormat::FormatRangeToParts), - reinterpret_cast(NumberFormat::NumberFormatConstructor), - reinterpret_cast(NumberFormat::SupportedLocalesOf), - reinterpret_cast(NumberFormat::Format), - reinterpret_cast(NumberFormat::FormatToParts), - reinterpret_cast(NumberFormat::ResolvedOptions), - reinterpret_cast(NumberFormat::NumberFormatInternalFormatNumber), - reinterpret_cast(RelativeTimeFormat::RelativeTimeFormatConstructor), - reinterpret_cast(RelativeTimeFormat::SupportedLocalesOf), - reinterpret_cast(RelativeTimeFormat::Format), - reinterpret_cast(RelativeTimeFormat::FormatToParts), - reinterpret_cast(RelativeTimeFormat::ResolvedOptions), - reinterpret_cast(Collator::CollatorConstructor), - reinterpret_cast(Collator::SupportedLocalesOf), - reinterpret_cast(Collator::Compare), - reinterpret_cast(Collator::ResolvedOptions), - reinterpret_cast(PluralRules::PluralRulesConstructor), - reinterpret_cast(PluralRules::SupportedLocalesOf), - reinterpret_cast(PluralRules::Select), - reinterpret_cast(PluralRules::ResolvedOptions), - reinterpret_cast(ArrayList::ArrayListConstructor), - reinterpret_cast(ArrayList::Add), - reinterpret_cast(ArrayList::Iterator), - - // not builtins method - reinterpret_cast(JSFunction::PrototypeSetter), - reinterpret_cast(JSFunction::PrototypeGetter), - reinterpret_cast(JSFunction::NameGetter), - reinterpret_cast(JSArray::LengthSetter), - reinterpret_cast(JSArray::LengthGetter), -}; - -SnapShotSerialize::SnapShotSerialize(EcmaVM *vm, bool serialize) : vm_(vm), serialize_(serialize) -{ - objectArraySize_ = OBJECT_SIZE_EXTEND_PAGE; - if (serialize_) { - addressSlot_ = ToUintPtr(vm_->GetRegionFactory()->Allocate(sizeof(uintptr_t) * OBJECT_SIZE_EXTEND_PAGE)); - } else { - addressSlot_ = ToUintPtr(vm_->GetRegionFactory()->Allocate(sizeof(uintptr_t) * objectArraySize_)); - } -} - -SnapShotSerialize::~SnapShotSerialize() -{ - if (serialize_) { - vm_->GetRegionFactory()->Free(ToVoidPtr(addressSlot_), sizeof(uintptr_t) * OBJECT_SIZE_EXTEND_PAGE); - } else { - vm_->GetRegionFactory()->Free(ToVoidPtr(addressSlot_), sizeof(uintptr_t) * objectArraySize_); - } -} - -void SnapShotSerialize::SetObjectSlotField(uintptr_t obj, size_t offset, uint64_t value) -{ - *reinterpret_cast(obj + offset) = value; -} - -void SnapShotSerialize::SetObjectSlotFieldUint32(uintptr_t obj, size_t offset, uint32_t value) -{ - *reinterpret_cast(obj + offset) = value; -} - -void SnapShotSerialize::Serialize(TaggedObject *objectHeader, CQueue *queue, - std::unordered_map *data) -{ - uint8_t objectType = SerializeHelper::GetObjectType(objectHeader); - size_t objectSize = objectHeader->GetClass()->SizeFromJSHClass(objectHeader); - if (objectSize > MAX_REGULAR_HEAP_OBJECT_SIZE) { - LOG_ECMA_MEM(FATAL) << "It is a huge object. Not Support."; - } - - if (objectSize == 0) { - LOG_ECMA_MEM(FATAL) << "It is a zero object. Not Support."; - } - - uintptr_t snapshotObj = vm_->GetFactory()->NewSpaceBySnapShotAllocator(objectSize); - if (snapshotObj == 0) { - LOG_ECMA(DEBUG) << "SnapShotAllocator OOM"; - return; - } - if (memcpy_s(ToVoidPtr(snapshotObj), objectSize, objectHeader, objectSize) != EOK) { - LOG_ECMA(FATAL) << "memcpy_s failed"; - UNREACHABLE(); - } - - // header - SlotBit headSlot = HandleObjectHeader(objectHeader, objectType, objectSize, queue, data); - SetObjectSlotField(snapshotObj, 0, headSlot.GetValue()); - - count_++; - LOG_IF(count_ > MAX_OBJECT_INDEX, FATAL, RUNTIME) << "objectCount: " + ToCString(count_); - LOG_IF(objectSize > MAX_OBJECT_SIZE_INDEX, FATAL, RUNTIME) << "objectSize: " + ToCString(objectSize); - switch (JSType(objectType)) { - case JSType::HCLASS: - DynClassSerialize(objectHeader, snapshotObj, objectSize, queue, data); - break; - case JSType::STRING: - DynStringSerialize(objectHeader, snapshotObj); - break; - case JSType::TAGGED_ARRAY: - case JSType::LINKED_HASH_SET: - case JSType::LINKED_HASH_MAP: - case JSType::TAGGED_DICTIONARY: - DynArraySerialize(objectHeader, snapshotObj, queue, data); - break; - case JSType::JS_NATIVE_POINTER: - NativePointerSerialize(objectHeader, snapshotObj); - break; - case JSType::PROGRAM: - DynProgramSerialize(objectHeader, snapshotObj, queue, data); - break; - case JSType::JS_FUNCTION_BASE: - case JSType::JS_FUNCTION: - case JSType::JS_PROXY_REVOC_FUNCTION: - case JSType::JS_PROMISE_REACTIONS_FUNCTION: - case JSType::JS_PROMISE_EXECUTOR_FUNCTION: - case JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION: - case JSType::JS_GENERATOR_FUNCTION: - case JSType::JS_ASYNC_FUNCTION: - case JSType::JS_ASYNC_GENERATOR_FUNCTION: - case JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION: - case JSType::JS_ASYNC_GENERATOR_RESOLVE_NEXT_FUNCTION: - case JSType::JS_ASYNC_FROM_SYNC_ITERATOR_VALUE_UNWRAP_FUNCTION: - case JSType::JS_BOUND_FUNCTION: - JSFunctionBaseSerialize(objectHeader, snapshotObj, objectSize, queue, data); - break; - case JSType::JS_PROXY: - JSProxySerialize(objectHeader, snapshotObj, objectSize, queue, data); - break; - default: - JSObjectSerialize(objectHeader, snapshotObj, objectSize, queue, data); - break; - } -} - -void SnapShotSerialize::ExtendObjectArray() -{ - int countNow = objectArraySize_; - objectArraySize_ = objectArraySize_ + OBJECT_SIZE_EXTEND_PAGE; - - auto addr = vm_->GetRegionFactory()->Allocate(sizeof(uintptr_t) * objectArraySize_); - int size = countNow * ADDRESS_SIZE; - if (memcpy_s(addr, size, ToVoidPtr(addressSlot_), size) != EOK) { - LOG_ECMA(FATAL) << "memcpy_s failed"; - UNREACHABLE(); - } - - vm_->GetRegionFactory()->Free(ToVoidPtr(addressSlot_), sizeof(uintptr_t) * objectArraySize_); - addressSlot_ = ToUintPtr(addr); -} - -void SnapShotSerialize::RedirectSlot(const panda_file::File *pf) -{ - SnapShotSpace *space = vm_->GetHeap()->GetSnapShotSpace(); - EcmaStringTable *stringTable = vm_->GetEcmaStringTable(); - - size_t others = 0; - space->EnumerateRegions([stringTable, &others, this, pf](Region *current) { - size_t allocated = current->GetAllocatedBytes(); - uintptr_t begin = current->GetBegin(); - uintptr_t end = begin + allocated; - while (begin < end) { - if (others != 0) { - for (size_t i = 0; i < others; i++) { - pandaMethod_.emplace_back(begin); - auto method = reinterpret_cast(begin); - method->SetPandaFile(pf); - method->SetBytecodeArray(method->GetInstructions()); - vm_->frameworkProgramMethods_.emplace_back(method); - begin += METHOD_SIZE; - if (begin >= end) { - others = others - i - 1; - } - } - break; - } - - if (count_ == objectArraySize_) { - ExtendObjectArray(); - } - SlotBit slot(*reinterpret_cast(begin)); - if (slot.GetObjectType() == MASK_METHOD_SPACE_BEGIN) { - begin += sizeof(uint64_t); - for (size_t i = 0; i < slot.GetObjectSize(); i++) { - pandaMethod_.emplace_back(begin); - auto method = reinterpret_cast(begin); - method->SetPandaFile(pf); - method->SetBytecodeArray(method->GetInstructions()); - vm_->frameworkProgramMethods_.emplace_back(method); - begin += METHOD_SIZE; - if (begin >= end) { - others = slot.GetObjectSize() - i - 1; - break; - } - } - break; - } - - if (JSType(slot.GetObjectType()) == JSType::STRING) { - stringTable->InsertStringIfNotExist(reinterpret_cast(begin)); - } - - SetAddressToSlot(count_, begin); - begin = begin + AlignUp(slot.GetObjectSize(), static_cast(MemAlignment::MEM_ALIGN_OBJECT)); - count_++; - } - }); - - auto constants = const_cast(vm_->GetJSThread()->GlobalConstants()); - for (int i = 0; i < count_; i++) { - SlotBit slot(*GetAddress(i)); - size_t objectSize = slot.GetObjectSize(); - uint8_t objectType = slot.GetObjectType(); - size_t index = slot.GetObjectInConstantsIndex(); - - switch (JSType(objectType)) { - case JSType::HCLASS: - DynClassDeserialize(GetAddress(i)); - break; - case JSType::STRING: - DynStringDeserialize(GetAddress(i)); - break; - case JSType::TAGGED_ARRAY: - case JSType::TAGGED_DICTIONARY: - case JSType::LINKED_HASH_SET: - case JSType::LINKED_HASH_MAP: - DynArrayDeserialize(GetAddress(i)); - break; - case JSType::JS_NATIVE_POINTER: - NativePointerDeserialize(GetAddress(i)); - break; - case JSType::GLOBAL_ENV: - JSObjectDeserialize(GetAddress(i), objectSize); - vm_->SetGlobalEnv(GetAddress(i)); - break; - case JSType::MICRO_JOB_QUEUE: - JSObjectDeserialize(GetAddress(i), objectSize); - vm_->SetMicroJobQueue(GetAddress(i)); - break; - case JSType::PROGRAM: - DynProgramDeserialize(GetAddress(i), objectSize); - vm_->frameworkProgram_ = JSTaggedValue(GetAddress(i)); - break; - case JSType::JS_FUNCTION_BASE: - case JSType::JS_FUNCTION: - case JSType::JS_PROXY_REVOC_FUNCTION: - case JSType::JS_PROMISE_REACTIONS_FUNCTION: - case JSType::JS_PROMISE_EXECUTOR_FUNCTION: - case JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION: - case JSType::JS_GENERATOR_FUNCTION: - case JSType::JS_ASYNC_FUNCTION: - case JSType::JS_ASYNC_GENERATOR_FUNCTION: - case JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION: - case JSType::JS_ASYNC_GENERATOR_RESOLVE_NEXT_FUNCTION: - case JSType::JS_ASYNC_FROM_SYNC_ITERATOR_VALUE_UNWRAP_FUNCTION: - case JSType::JS_BOUND_FUNCTION: - JSFunctionBaseDeserialize(GetAddress(i), objectSize); - break; - case JSType::JS_PROXY: - JSProxyDeserialize(GetAddress(i), objectSize); - break; - default: - JSObjectDeserialize(GetAddress(i), objectSize); - break; - } - if (index != 0) { - JSTaggedValue result(GetAddress(i)); - constants->SetConstant(ConstantIndex(index - 1), result); - } - } -} - -SlotBit SnapShotSerialize::HandleObjectHeader(TaggedObject *objectHeader, uint8_t objectType, size_t objectSize, - CQueue *queue, - std::unordered_map *data) -{ - auto *hclassClass = objectHeader->GetClass(); - SlotBit slot(0); - - ASSERT(hclassClass != nullptr); - if (data->find(ToUintPtr(hclassClass)) == data->end()) { - slot = SerializeHelper::AddObjectHeaderToData(hclassClass, queue, data); - } else { - slot = data->find(ToUintPtr(hclassClass))->second; - } - - SlotBit objectSlotBit = data->find(ToUintPtr(objectHeader))->second; - slot.SetObjectInConstantsIndex(objectSlotBit.GetObjectInConstantsIndex()); - slot.SetObjectSize(objectSize); - slot.SetObjectType(objectType); - return slot; -} - -uint64_t SnapShotSerialize::HandleTaggedField(JSTaggedType *tagged, CQueue *queue, - std::unordered_map *data) -{ - JSTaggedValue taggedValue(*tagged); - if (taggedValue.IsWeak()) { - return JSTaggedValue::Undefined().GetRawData(); // Undefind - } - - if (taggedValue.IsSpecial()) { - SlotBit special(taggedValue.GetRawData()); - special.SetObjectSpecial(); - return special.GetValue(); // special slot - } - - if (!taggedValue.IsHeapObject()) { - return taggedValue.GetRawData(); // not object - } - - SlotBit slotBit(0); - if (data->find(*tagged) == data->end()) { - slotBit = SerializeHelper::AddObjectHeaderToData(taggedValue.GetTaggedObject(), queue, data); - } else { - slotBit = data->find(taggedValue.GetRawData())->second; - } - - if (taggedValue.IsString()) { - slotBit.SetReferenceToString(true); - } - return slotBit.GetValue(); // object -} - -void SnapShotSerialize::DeserializeHandleTaggedField(uint64_t *value) -{ - SlotBit slot(*value); - if (slot.IsReferenceSlot() && !slot.IsSpecial()) { - uint32_t index = slot.GetObjectIndex(); - - if (slot.IsReferenceToString()) { - auto str = vm_->GetEcmaStringTable()->GetString(GetAddress(index)); - ASSERT(str != nullptr); - *value = ToUintPtr(str); - } else { - *value = GetAddress(index); - } - return; - } - - if (slot.IsSpecial()) { - slot.ClearObjectSpecialFlag(); - *value = slot.GetValue(); - } -} - -void SnapShotSerialize::DeserializeHandleClassWord(TaggedObject *object) -{ - SlotBit slot(*reinterpret_cast(object)); - ASSERT(slot.IsReferenceSlot()); - uint32_t index = slot.GetObjectIndex(); - *reinterpret_cast(object) = 0; - - object->SetClass(GetAddress(index)); -} - -void SnapShotSerialize::DynClassSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, size_t objectSize, - CQueue *queue, std::unordered_map *data) -{ - size_t beginOffset = JSHClass::PROTOTYPE_OFFSET; - int numOfFields = static_cast((objectSize - beginOffset) / TAGGED_SIZE); - uintptr_t startAddr = ToUintPtr(objectHeader) + beginOffset; - for (int i = 0; i < numOfFields; i++) { - auto fieldAddr = reinterpret_cast(startAddr + i * TAGGED_SIZE); - SetObjectSlotField(snapshotObj, beginOffset + i * TAGGED_SIZE, HandleTaggedField(fieldAddr, queue, data)); - } -} - -void SnapShotSerialize::DynClassDeserialize(uint64_t *objectHeader) -{ - auto dynClass = reinterpret_cast(objectHeader); - // handle object_header - DeserializeHandleClassWord(dynClass); - - uintptr_t startAddr = ToUintPtr(dynClass) + JSHClass::PROTOTYPE_OFFSET; - int numOfFields = static_cast((JSHClass::SIZE - JSHClass::PROTOTYPE_OFFSET) / TAGGED_SIZE); - for (int i = 0; i < numOfFields; i++) { - auto fieldAddr = reinterpret_cast(startAddr + i * TAGGED_SIZE); - DeserializeHandleTaggedField(fieldAddr); - } -} - -void SnapShotSerialize::DynStringSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj) -{ - auto *str = EcmaString::Cast(objectHeader); - SetObjectSlotFieldUint32(snapshotObj, OBJECT_HEADER_SIZE, str->GetLength() << 2U); -} - -void SnapShotSerialize::DynStringDeserialize(uint64_t *objectHeader) -{ - auto object = reinterpret_cast(objectHeader); - // handle object_header - DeserializeHandleClassWord(object); -} - -void SnapShotSerialize::DynArraySerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, - CQueue *queue, std::unordered_map *data) -{ - auto arrayObject = reinterpret_cast(objectHeader); - size_t beginOffset = TaggedArray::DATA_OFFSET; - auto arrayLength = arrayObject->GetLength(); - uintptr_t startAddr = ToUintPtr(objectHeader) + beginOffset; - for (uint32_t i = 0; i < arrayLength; i++) { - auto fieldAddr = reinterpret_cast(startAddr + i * TAGGED_SIZE); - SetObjectSlotField(snapshotObj, beginOffset + i * TAGGED_SIZE, HandleTaggedField(fieldAddr, queue, data)); - } -} - -void SnapShotSerialize::DynArrayDeserialize(uint64_t *objectHeader) -{ - auto object = reinterpret_cast(objectHeader); - // handle object_header - DeserializeHandleClassWord(object); - - auto arrayLength = object->GetLength(); - size_t dataOffset = TaggedArray::DATA_OFFSET; - uintptr_t startAddr = ToUintPtr(objectHeader) + dataOffset; - for (uint32_t i = 0; i < arrayLength; i++) { - auto fieldAddr = reinterpret_cast(startAddr + i * TAGGED_SIZE); - DeserializeHandleTaggedField(fieldAddr); - } -} - -SlotBit SnapShotSerialize::NativePointerToSlotBit(void *nativePointer) -{ - SlotBit native(0); - if (nativePointer != nullptr) { // nativePointer - uint32_t index = MAX_UINT_32; - - if (programSerialize_) { - pandaMethod_.emplace_back(ToUintPtr(nativePointer)); - // NOLINTNEXTLINE(bugprone-narrowing-conversions, cppcoreguidelines-narrowing-conversions) - index = pandaMethod_.size() + PROGRAM_NATIVE_METHOD_BEGIN + NATIVE_METHOD_SIZE - 1; - } else { - for (size_t i = 0; i < PROGRAM_NATIVE_METHOD_BEGIN; i++) { - if (nativePointer == reinterpret_cast(g_nativeTable[i + NATIVE_METHOD_SIZE])) { - index = i + NATIVE_METHOD_SIZE; - break; - } - } - - // not found - if (index == MAX_UINT_32) { - auto nativeMethod = reinterpret_cast(nativePointer)->GetNativePointer(); - for (size_t i = 0; i < NATIVE_METHOD_SIZE; i++) { - if (nativeMethod == GetAddress(i)) { - index = i; - break; - } - } - } - } - - ASSERT(index != MAX_UINT_32); - LOG_IF(index > MAX_C_POINTER_INDEX, FATAL, RUNTIME) << "MAX_C_POINTER_INDEX: " + ToCString(index); - native.SetObjectIndex(index); - } - return native; -} - -void *SnapShotSerialize::NativePointerSlotBitToAddr(SlotBit native) -{ - uint32_t index = native.GetObjectIndex(); - void *addr = nullptr; - - if (index < NATIVE_METHOD_SIZE) { - addr = reinterpret_cast(vm_->nativeMethods_.at(index)); - } else if (index < NATIVE_METHOD_SIZE + PROGRAM_NATIVE_METHOD_BEGIN) { - addr = reinterpret_cast(g_nativeTable[index]); - } else { - addr = ToVoidPtr(pandaMethod_.at(index - PROGRAM_NATIVE_METHOD_BEGIN - NATIVE_METHOD_SIZE)); - } - return addr; -} - -void SnapShotSerialize::NativePointerSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj) -{ - void *nativePointer = JSNativePointer::Cast(objectHeader)->GetExternalPointer(); - SetObjectSlotField(snapshotObj, OBJECT_HEADER_SIZE, NativePointerToSlotBit(nativePointer).GetValue()); -} - -void SnapShotSerialize::NativePointerDeserialize(uint64_t *objectHeader) -{ - auto object = reinterpret_cast(objectHeader); - // handle object_header - DeserializeHandleClassWord(object); - - size_t nativeAddr = ToUintPtr(object) + OBJECT_HEADER_SIZE; - SlotBit native(*reinterpret_cast(nativeAddr)); - if (native.GetObjectIndex() == MAX_OBJECT_INDEX) { - return; - } - JSNativePointer::Cast(object)->ResetExternalPointer(NativePointerSlotBitToAddr(native)); -} - -void SnapShotSerialize::JSObjectSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, size_t objectSize, - CQueue *queue, std::unordered_map *data) -{ - int numOfFields = static_cast((objectSize - OBJECT_HEADER_SIZE) / TAGGED_SIZE); - uintptr_t startAddr = ToUintPtr(objectHeader) + OBJECT_HEADER_SIZE; - for (int i = 0; i < numOfFields; i++) { - auto fieldAddr = reinterpret_cast(startAddr + i * TAGGED_SIZE); - SetObjectSlotField(snapshotObj, OBJECT_HEADER_SIZE + i * TAGGED_SIZE, - HandleTaggedField(fieldAddr, queue, data)); - } -} - -void SnapShotSerialize::JSFunctionBaseSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, size_t objectSize, - CQueue *queue, - std::unordered_map *data) -{ - // befour - int befourFields = static_cast((JSFunctionBase::METHOD_OFFSET - OBJECT_HEADER_SIZE) / TAGGED_SIZE); - uintptr_t befourStartAddr = ToUintPtr(objectHeader) + OBJECT_HEADER_SIZE; - for (int i = 0; i < befourFields; i++) { - auto fieldAddr = reinterpret_cast(befourStartAddr + i * TAGGED_SIZE); - SetObjectSlotField(snapshotObj, OBJECT_HEADER_SIZE + i * TAGGED_SIZE, - HandleTaggedField(fieldAddr, queue, data)); - } - - // method - auto functionBase = static_cast(objectHeader); - size_t methodOffset = functionBase->OffsetMethod(); - auto nativePointer = reinterpret_cast(functionBase->GetMethod()); - SetObjectSlotField(snapshotObj, methodOffset, NativePointerToSlotBit(nativePointer).GetValue()); - - // after - size_t afterOffset = JSFunctionBase::METHOD_OFFSET + TAGGED_SIZE; - int afterFields = static_cast((objectSize - afterOffset) / TAGGED_SIZE); - uintptr_t afterStartAddr = ToUintPtr(objectHeader) + JSFunctionBase::METHOD_OFFSET + TAGGED_SIZE; - for (int i = 0; i < afterFields; i++) { - auto fieldAddr = reinterpret_cast(afterStartAddr + i * TAGGED_SIZE); - SetObjectSlotField(snapshotObj, afterOffset + i * TAGGED_SIZE, HandleTaggedField(fieldAddr, queue, data)); - } -} - -void SnapShotSerialize::JSProxySerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, size_t objectSize, - CQueue *queue, std::unordered_map *data) -{ - // befour - int befourFields = static_cast((JSProxy::METHOD_OFFSET - OBJECT_HEADER_SIZE) / TAGGED_SIZE); - uintptr_t befourStartAddr = ToUintPtr(objectHeader) + OBJECT_HEADER_SIZE; - for (int i = 0; i < befourFields; i++) { - auto fieldAddr = reinterpret_cast(befourStartAddr + i * TAGGED_SIZE); - SetObjectSlotField(snapshotObj, OBJECT_HEADER_SIZE + i * TAGGED_SIZE, - HandleTaggedField(fieldAddr, queue, data)); - } - - // method - auto jsproxy = static_cast(objectHeader); - size_t methodOffset = jsproxy->OffsetMethod(); - auto nativePointer = reinterpret_cast(jsproxy->GetMethod()); - SetObjectSlotField(snapshotObj, methodOffset, NativePointerToSlotBit(nativePointer).GetValue()); - - // after - size_t afterOffset = JSProxy::METHOD_OFFSET + TAGGED_SIZE; - int afterFields = static_cast((objectSize - afterOffset) / TAGGED_SIZE); - uintptr_t afterStartAddr = ToUintPtr(objectHeader) + JSProxy::METHOD_OFFSET + TAGGED_SIZE; - for (int i = 0; i < afterFields; i++) { - auto fieldAddr = reinterpret_cast(afterStartAddr + i * TAGGED_SIZE); - SetObjectSlotField(snapshotObj, afterOffset + i * TAGGED_SIZE, HandleTaggedField(fieldAddr, queue, data)); - } -} - -void SnapShotSerialize::DeserializeRangeTaggedField(size_t beginAddr, int numOfFields) -{ - for (int i = 0; i < numOfFields; i++) { - auto fieldAddr = reinterpret_cast(beginAddr + i * TAGGED_SIZE); - DeserializeHandleTaggedField(fieldAddr); - } -} - -void SnapShotSerialize::JSObjectDeserialize(uint64_t *objectHeader, size_t objectSize) -{ - auto object = reinterpret_cast(objectHeader); - // handle object_header - DeserializeHandleClassWord(object); - - auto objBodySize = objectSize - OBJECT_HEADER_SIZE; - ASSERT(objBodySize % TAGGED_SIZE == 0); - int numOfFields = static_cast(objBodySize / TAGGED_SIZE); - size_t addr = ToUintPtr(objectHeader) + OBJECT_HEADER_SIZE; - DeserializeRangeTaggedField(addr, numOfFields); -} - -void SnapShotSerialize::JSFunctionBaseDeserialize(uint64_t *objectHeader, size_t objectSize) -{ - auto object = reinterpret_cast(objectHeader); - DeserializeHandleClassWord(object); - - // befour - auto befourMethod = JSFunctionBase::METHOD_OFFSET - OBJECT_HEADER_SIZE; - ASSERT(befourMethod % TAGGED_SIZE == 0); - int befourMethodFields = static_cast(befourMethod / TAGGED_SIZE); - size_t befourAddr = ToUintPtr(objectHeader) + OBJECT_HEADER_SIZE; - DeserializeRangeTaggedField(befourAddr, befourMethodFields); - - // method - size_t nativeAddr = ToUintPtr(object) + JSFunctionBase::METHOD_OFFSET; - SlotBit native(*reinterpret_cast(nativeAddr)); - if (native.GetObjectIndex() != MAX_OBJECT_INDEX) { - object->SetMethod(reinterpret_cast(NativePointerSlotBitToAddr(native))); - } - - // after - auto afterMethod = objectSize - JSFunctionBase::METHOD_OFFSET - TAGGED_SIZE; - ASSERT(afterMethod % TAGGED_SIZE == 0); - int afterMethodFields = static_cast(afterMethod / TAGGED_SIZE); - size_t afterAddr = ToUintPtr(objectHeader) + JSFunctionBase::METHOD_OFFSET + TAGGED_SIZE; - DeserializeRangeTaggedField(afterAddr, afterMethodFields); -} - -void SnapShotSerialize::JSProxyDeserialize(uint64_t *objectHeader, size_t objectSize) -{ - auto object = reinterpret_cast(objectHeader); - DeserializeHandleClassWord(object); - - // befour - auto befourMethod = JSProxy::METHOD_OFFSET - OBJECT_HEADER_SIZE; - ASSERT(befourMethod % TAGGED_SIZE == 0); - int befourMethodFields = static_cast(befourMethod / TAGGED_SIZE); - size_t befourAddr = ToUintPtr(objectHeader) + OBJECT_HEADER_SIZE; - DeserializeRangeTaggedField(befourAddr, befourMethodFields); - - // method - size_t nativeAddr = ToUintPtr(object) + JSProxy::METHOD_OFFSET; - SlotBit native(*reinterpret_cast(nativeAddr)); - if (native.GetObjectIndex() != MAX_OBJECT_INDEX) { - object->SetMethod(reinterpret_cast(NativePointerSlotBitToAddr(native))); - } - - // after - auto afterMethod = objectSize - JSProxy::METHOD_OFFSET - TAGGED_SIZE; - ASSERT(afterMethod % TAGGED_SIZE == 0); - int afterMethodFields = static_cast(afterMethod / TAGGED_SIZE); - size_t afterAddr = ToUintPtr(objectHeader) + JSProxy::METHOD_OFFSET + TAGGED_SIZE; - DeserializeRangeTaggedField(afterAddr, afterMethodFields); -} - -void SnapShotSerialize::DynProgramSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, - CQueue *queue, - std::unordered_map *data) -{ - size_t beginOffset = OBJECT_HEADER_SIZE; - auto objBodySize = Program::METHODS_DATA_OFFSET - OBJECT_HEADER_SIZE; - int numOfFields = static_cast((objBodySize) / TAGGED_SIZE); - uintptr_t startAddr = ToUintPtr(objectHeader) + beginOffset; - for (int i = 0; i < numOfFields; i++) { - auto fieldAddr = reinterpret_cast(startAddr + i * TAGGED_SIZE); - SetObjectSlotField(snapshotObj, beginOffset + i * TAGGED_SIZE, HandleTaggedField(fieldAddr, queue, data)); - } - SetObjectSlotField(snapshotObj, Program::METHODS_DATA_OFFSET, 0); // methods -} - -void SnapShotSerialize::DynProgramDeserialize(uint64_t *objectHeader, [[maybe_unused]] size_t objectSize) -{ - auto object = reinterpret_cast(objectHeader); - // handle object_header - DeserializeHandleClassWord(object); - - auto objBodySize = Program::METHODS_DATA_OFFSET - OBJECT_HEADER_SIZE; - ASSERT(objBodySize % TAGGED_SIZE == 0); - int numOfFields = static_cast(objBodySize / TAGGED_SIZE); - size_t addr = ToUintPtr(objectHeader) + OBJECT_HEADER_SIZE; - for (int i = 0; i < numOfFields; i++) { - auto fieldAddr = reinterpret_cast(addr + i * TAGGED_SIZE); - DeserializeHandleTaggedField(fieldAddr); - } - - auto program = reinterpret_cast(objectHeader); - program->SetMethodsData(nullptr); -} - -void SnapShotSerialize::SerializePandaFileMethod() -{ - SlotBit slot(0); - slot.SetObjectType(MASK_METHOD_SPACE_BEGIN); - slot.SetObjectSize(pandaMethod_.size()); - - ObjectFactory *factory = vm_->GetFactory(); - // panda method space begin - uintptr_t snapshotObj = factory->NewSpaceBySnapShotAllocator(sizeof(uint64_t)); - if (snapshotObj == 0) { - LOG(ERROR, RUNTIME) << "SnapShotAllocator OOM"; - return; - } - SetObjectSlotField(snapshotObj, 0, slot.GetValue()); // methods - - // panda methods - for (auto &it : pandaMethod_) { - // write method - size_t methodObjSize = METHOD_SIZE; - uintptr_t methodObj = factory->NewSpaceBySnapShotAllocator(methodObjSize); - if (methodObj == 0) { - LOG(ERROR, RUNTIME) << "SnapShotAllocator OOM"; - return; - } - if (memcpy_s(ToVoidPtr(methodObj), methodObjSize, ToVoidPtr(it), METHOD_SIZE) != EOK) { - LOG_ECMA(FATAL) << "memcpy_s failed"; - UNREACHABLE(); - } - } -} - -void SnapShotSerialize::RegisterNativeMethod() // NOLINT(readability-function-size) -{ - constexpr int size = sizeof(g_nativeTable) / sizeof(uintptr_t); - ASSERT(size == NATIVE_METHOD_SIZE + PROGRAM_NATIVE_METHOD_BEGIN); - for (int i = 0; i < size; i++) { - SetAddressToSlot(i, g_nativeTable[i]); - } -} - -void SnapShotSerialize::GeneratedNativeMethod() // NOLINT(readability-function-size) -{ - for (int i = 0; i < NATIVE_METHOD_SIZE; i++) { - SetAddressToSlot(i, g_nativeTable[i]); - vm_->GetMethodForNativeFunction(reinterpret_cast(g_nativeTable[i])); - } -} -} // namespace panda::ecmascript diff --git a/runtime/snapshot/mem/snapshot_serialize.h b/runtime/snapshot/mem/snapshot_serialize.h deleted file mode 100644 index f14c12876149a353d3d0efe7bd303d0c75a79505..0000000000000000000000000000000000000000 --- a/runtime/snapshot/mem/snapshot_serialize.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_SERIALIZE_H -#define ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_SERIALIZE_H - -#include -#include -#include - -#include "libpandabase/macros.h" -#include "plugins/ecmascript/runtime/snapshot/mem/slot_bit.h" -#include "plugins/ecmascript/runtime/js_tagged_value.h" - -namespace panda::ecmascript { -class EcmaVM; - -class SnapShotSerialize final { -public: - explicit SnapShotSerialize(EcmaVM *vm, bool serialize); - ~SnapShotSerialize(); - - void Serialize(TaggedObject *objectHeader, CQueue *queue, - std::unordered_map *data); - void RedirectSlot(const panda_file::File *pf); - void SerializePandaFileMethod(); - - void SetProgramSerializeStart() - { - programSerialize_ = true; - } - - void RegisterNativeMethod(); - void GeneratedNativeMethod(); - -private: - void SetObjectSlotField(uintptr_t obj, size_t offset, uint64_t value); - void SetObjectSlotFieldUint32(uintptr_t obj, size_t offset, uint32_t value); - - void NativePointerSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj); - void JSObjectSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, size_t objectSize, - CQueue *queue, std::unordered_map *data); - void JSFunctionBaseSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, size_t objectSize, - CQueue *queue, - std::unordered_map *data); - void JSProxySerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, size_t objectSize, - CQueue *queue, std::unordered_map *data); - void DynClassSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, size_t objectSize, - CQueue *queue, std::unordered_map *data); - void DynArraySerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, CQueue *queue, - std::unordered_map *data); - void DynStringSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj); - void DynProgramSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, CQueue *queue, - std::unordered_map *data); - - void NativePointerDeserialize(uint64_t *objectHeader); - void JSObjectDeserialize(uint64_t *objectHeader, size_t objectSize); - void JSFunctionBaseDeserialize(uint64_t *objectHeader, size_t objectSize); - void JSProxyDeserialize(uint64_t *objectHeader, size_t objectSize); - void DynClassDeserialize(uint64_t *objectHeader); - void DynStringDeserialize(uint64_t *objectHeader); - void DynArrayDeserialize(uint64_t *objectHeader); - void DynProgramDeserialize(uint64_t *objectHeader, size_t objectSize); - - SlotBit HandleObjectHeader(TaggedObject *objectHeader, uint8_t objectType, size_t objectSize, - CQueue *queue, std::unordered_map *data); - uint64_t HandleTaggedField(JSTaggedType *tagged, CQueue *queue, - std::unordered_map *data); - void DeserializeHandleTaggedField(uint64_t *value); - void DeserializeHandleClassWord(TaggedObject *object); - void ExtendObjectArray(); - - void SetAddressToSlot(size_t index, uintptr_t value) - { - auto addr = reinterpret_cast(addressSlot_ + index * ADDRESS_SIZE); - // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) - *addr = value; - } - - template - T GetAddress(size_t index) - { - return *reinterpret_cast(addressSlot_ + index * ADDRESS_SIZE); - } - - SlotBit NativePointerToSlotBit(void *nativePointer); - void *NativePointerSlotBitToAddr(SlotBit native); - void DeserializeRangeTaggedField(size_t beginAddr, int numOfFields); - - EcmaVM *vm_ {nullptr}; - bool serialize_ {false}; - bool programSerialize_ {false}; - int count_ {0}; - int objectArraySize_ {0}; - uintptr_t addressSlot_; - CVector pandaMethod_; - - NO_COPY_SEMANTIC(SnapShotSerialize); - NO_MOVE_SEMANTIC(SnapShotSerialize); -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_SERIALIZE_H diff --git a/runtime/tagged_dictionary.cpp b/runtime/tagged_dictionary.cpp index 2c8ea7ea46de0715e2cd9596ac4f70e1a47ae88e..b64b1c1f32bb23a12e3c673d00e36c8c27e5583c 100644 --- a/runtime/tagged_dictionary.cpp +++ b/runtime/tagged_dictionary.cpp @@ -43,7 +43,7 @@ void NameDictionary::GetAllKeys(const JSThread *thread, int offset, TaggedArray { int arrayIndex = 0; int size = Size(); - CVector> sortArr; + PandaVector> sortArr; for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key = GetKey(hashIndex); if (!key.IsUndefined() && !key.IsHole()) { @@ -63,7 +63,7 @@ void NameDictionary::GetAllEnumKeys(const JSThread *thread, int offset, TaggedAr { uint32_t arrayIndex = 0; int size = Size(); - CVector> sortArr; + PandaVector> sortArr; for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key = GetKey(hashIndex); if (key.IsString()) { @@ -159,7 +159,7 @@ void NumberDictionary::GetAllKeys(const JSThread *thread, const JSHandleSize(); - CVector sortArr; + PandaVector sortArr; for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key = obj->GetKey(hashIndex); if (!key.IsUndefined() && !key.IsHole()) { @@ -183,7 +183,7 @@ void NumberDictionary::GetAllEnumKeys(const JSThread *thread, const JSHandleSize(); - CVector sortArr; + PandaVector sortArr; for (int hashIndex = 0; hashIndex < size; hashIndex++) { JSTaggedValue key = obj->GetKey(hashIndex); if (!key.IsUndefined() && !key.IsHole()) { diff --git a/runtime/tooling/pt_js_extractor.h b/runtime/tooling/pt_js_extractor.h index c65b73c14488dedb63faedd403ebacc2a955eb73..cbd997185ca9470ccce6a8af1a421704c8436d1c 100644 --- a/runtime/tooling/pt_js_extractor.h +++ b/runtime/tooling/pt_js_extractor.h @@ -18,7 +18,6 @@ #include "plugins/ecmascript/runtime/js_method.h" #include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "libpandafile/debug_info_extractor.h" #include "libpandabase/macros.h" #include "include/tooling/debug_interface.h" diff --git a/runtime/vmstat/caller_stat.h b/runtime/vmstat/caller_stat.h index a8cd57359750a1d82f6287cb8b983887124a9439..9ccdc3da934d8aa4cfe2de7e2a8ac5c65b20c546 100644 --- a/runtime/vmstat/caller_stat.h +++ b/runtime/vmstat/caller_stat.h @@ -20,7 +20,8 @@ #include #include -#include "plugins/ecmascript/runtime/mem/c_string.h" +#include "plugins/ecmascript/runtime/mem/ecma_string.h" +#include "runtime/include/mem/panda_string.h" #include "libpandabase/macros.h" namespace panda::ecmascript { @@ -28,7 +29,7 @@ class EcmaRuntimeStat; class PandaRuntimeCallerStat { public: // NOLINTNEXTLINE(modernize-pass-by-value) - explicit PandaRuntimeCallerStat(const CString &name) : name_(name) {} + explicit PandaRuntimeCallerStat(const PandaString &name) : name_(name) {} PandaRuntimeCallerStat() = default; virtual ~PandaRuntimeCallerStat() = default; @@ -66,7 +67,7 @@ public: } private: - CString name_ {}; + PandaString name_ {}; uint64_t totalCount_ {0}; uint64_t totalTime_ {0}; uint64_t maxTime_ {0}; diff --git a/runtime/vmstat/runtime_stat.cpp b/runtime/vmstat/runtime_stat.cpp index 093bc7120459c100d9b2478c2119e4043afeeb77..a9cf7b09bc58c86779d06413042a3cf0f33a3dc2 100644 --- a/runtime/vmstat/runtime_stat.cpp +++ b/runtime/vmstat/runtime_stat.cpp @@ -26,7 +26,7 @@ EcmaRuntimeStat::EcmaRuntimeStat(const char *const runtimeCallerNames[], int cou { for (int i = 0; i < count; i++) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - callerStat_.emplace_back(PandaRuntimeCallerStat(CString(runtimeCallerNames[i]))); + callerStat_.emplace_back(PandaRuntimeCallerStat(PandaString(runtimeCallerNames[i]))); } } @@ -68,9 +68,9 @@ void EcmaRuntimeStat::ResetAllCount() } } -CString EcmaRuntimeStat::GetAllStats() const +PandaString EcmaRuntimeStat::GetAllStats() const { - CStringStream statistic; + PandaStringStream statistic; statistic << "panda runtime stat:" << std::endl; static constexpr int nameRightAdjustment = 50; static constexpr int numberRightAdjustment = 20; diff --git a/runtime/vmstat/runtime_stat.h b/runtime/vmstat/runtime_stat.h index 5c66d071b9130dbfb6c222b5ce5ee396cfb7eada..8daa6a8e040da1397cf34c834dedee79db2a4e72 100644 --- a/runtime/vmstat/runtime_stat.h +++ b/runtime/vmstat/runtime_stat.h @@ -18,7 +18,6 @@ #include "plugins/ecmascript/runtime/ecma_vm.h" #include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" #include "plugins/ecmascript/runtime/vmstat/caller_stat.h" namespace panda::ecmascript { @@ -34,13 +33,13 @@ public: void StartCount(PandaRuntimeTimer *timer, int callerId); void StopCount(const PandaRuntimeTimer *timer); - CString GetAllStats() const; + PandaString GetAllStats() const; void ResetAllCount(); void Print() const; private: PandaRuntimeTimer *currentTimer_ = nullptr; - CVector callerStat_ {}; + PandaVector callerStat_ {}; }; class RuntimeTimerScope { diff --git a/tests/runtime/CMakeLists.txt b/tests/runtime/CMakeLists.txt index b5515696ebf079cfa183d197ad1c5c647d86e050..57b48d40f62f683d46e9e1eed3fda66c60f64298 100644 --- a/tests/runtime/CMakeLists.txt +++ b/tests/runtime/CMakeLists.txt @@ -20,24 +20,17 @@ add_subdirectory(irtoc) ## for performance consideration, each test suite should not be oversize, neither too small ## ## the principle is make a solo suite for case over 1000 lines ## set(ECMASCRIPT_TESTS_SOURCES - snapshot/snapshot_test.cpp common/name_dictionary_test.cpp common/native_pointer_test.cpp common/object_factory_test.cpp common/linked_hash_table_test.cpp - #common/dump_test.cpp - common/assert_scope_test.cpp - common/js_verification_test.cpp common/large_object_test.cpp common/glue_regs_test.cpp common/test_helper.cpp ) set(ECMASCRIPT_TEST_SOURCES-2 - #common/concurrent_marking_test.cpp #common/concurrent_sweep_test.cpp - #common/gc_test.cpp - #common/mem_controller_test.cpp #common/weak_ref_gen_gc_test.cpp #common/weak_ref_stw_gc_test.cpp common/ecma_module_test.cpp @@ -179,12 +172,6 @@ set(ECMASCRIPT_BUILTINS_TYPEDARRAY_TESTS_SOURCES common/test_helper.cpp ) -set(ECMASCRIPT_HPROF_TESTS_SOURCES - hprof/hprof_test.cpp - hprof/heap_tracker_test.cpp - common/test_helper.cpp -) - #0 panda_add_gtest( NO_CORES @@ -585,25 +572,6 @@ if(TARGET arkruntime4ecmascript_builtins_typedarray_tests) target_compile_options(arkruntime4ecmascript_builtins_typedarray_tests PUBLIC "-Wno-ignored-attributes") endif() #18 -panda_add_gtest( - NO_CORES - NAME arkruntime4ecmascript_hprof_tests - SOURCES - ${ECMASCRIPT_HPROF_TESTS_SOURCES} - LIBRARIES - arkruntime arkassembler - INCLUDE_DIRS - ${PANDA_ECMASCRIPT_PLUGIN_SOURCE}/tests/runtime/common - SANITIZERS - ${PANDA_SANITIZERS_LIST} -) -if(TARGET arkruntime4ecmascript_hprof_tests) - target_include_directories(arkruntime4ecmascript_hprof_tests - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} - ) - target_compile_options(arkruntime4ecmascript_hprof_tests PUBLIC "-Wno-ignored-attributes") -endif() -#19 panda_add_gtest( NO_CORES NAME arkruntime4ecmascript_separate_jsvm @@ -616,7 +584,7 @@ NAME arkruntime4ecmascript_separate_jsvm SANITIZERS ${PANDA_SANITIZERS_LIST} ) -#20 +#19 panda_add_gtest( NO_CORES NAME arkruntime4ecmascript_mem_tests @@ -628,7 +596,7 @@ panda_add_gtest( SANITIZERS ${PANDA_SANITIZERS_LIST} ) -#21 +#20 panda_add_gtest( NO_CORES NAME arkruntime4ecmascript_builtins_promise_tests @@ -647,7 +615,7 @@ if(TARGET arkruntime4ecmascript_builtins_promise_tests) ) target_compile_options(arkruntime4ecmascript_builtins_promise_tests PUBLIC "-Wno-ignored-attributes") endif() -#22 +#21 panda_add_gtest( NO_CORES NAME arkruntime4ecmascript_tests2 diff --git a/tests/runtime/builtins/builtins_array_test.cpp b/tests/runtime/builtins/builtins_array_test.cpp index ba19fbf0822287f2472c39835bb455df228a7553..a2997dbd4c002dbea1c699c804c8ba3ef1b94c7d 100644 --- a/tests/runtime/builtins/builtins_array_test.cpp +++ b/tests/runtime/builtins/builtins_array_test.cpp @@ -167,7 +167,7 @@ public: }; }; -JSTaggedValue CreateBuiltinsJSObject(JSThread *thread, const CString keyCStr) +JSTaggedValue CreateBuiltinsJSObject(JSThread *thread, const PandaString keyCStr) { EcmaVM *ecmaVM = thread->GetEcmaVM(); JSHandle globalEnv = ecmaVM->GetGlobalEnv(); diff --git a/tests/runtime/builtins/builtins_date_test.cpp b/tests/runtime/builtins/builtins_date_test.cpp index aef29594852b7161f6b6e58b5ba3660430eb0ed5..d589fa3b5598552c2459db885e1fd101494d805a 100644 --- a/tests/runtime/builtins/builtins_date_test.cpp +++ b/tests/runtime/builtins/builtins_date_test.cpp @@ -740,9 +740,9 @@ TEST_F(BuiltinsDateTest, ToJSONMinus) ASSERT_TRUE(EcmaString::StringsAreEqual(reinterpret_cast(result1.GetRawData()), *expect_value)); } -static CString GetLocalTime(JSHandle jsDate, int64_t localMin) +static PandaString GetLocalTime(JSHandle jsDate, int64_t localMin) { - CString localTime = ""; + PandaString localTime = ""; localMin = JSDate::GetLocalOffsetFromOS(localMin, true); if (static_cast(JSDate::Cast(jsDate.GetTaggedValue().GetTaggedObject())->GetTimeValue().GetDouble()) < CHINA_BEFORE_1900_MS && @@ -755,14 +755,14 @@ static CString GetLocalTime(JSHandle jsDate, int64_t localMin) localTime += NEG; localMin = -localMin; } - localTime = localTime + JSDate::StrToTargetLength(ToCString(localMin / MINUTE_PER_HOUR), STR_LENGTH_OTHERS); - return localTime + JSDate::StrToTargetLength(ToCString(localMin % MINUTE_PER_HOUR), STR_LENGTH_OTHERS); + localTime = localTime + JSDate::StrToTargetLength(ToPandaString(localMin / MINUTE_PER_HOUR), STR_LENGTH_OTHERS); + return localTime + JSDate::StrToTargetLength(ToPandaString(localMin % MINUTE_PER_HOUR), STR_LENGTH_OTHERS); } TEST_F(BuiltinsDateTest, ToString) { int localMin = 0; - CString localTime; + PandaString localTime; JSHandle jsDate = JSDateCreateTest(thread); auto ecmaRuntimeCallInfo = CreateAndSetRuntimeCallInfo(thread, 4, jsDate.GetTaggedValue()); @@ -775,7 +775,7 @@ TEST_F(BuiltinsDateTest, ToString) ASSERT_TRUE(result1.IsString()); TestHelper::TearDownFrame(thread, prev); JSHandle result1_val(thread, reinterpret_cast(result1.GetRawData())); - CString str = "Tue Nov 06 2018 18:10:06 GMT" + localTime; + PandaString str = "Tue Nov 06 2018 18:10:06 GMT" + localTime; JSHandle str_handle = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str); ASSERT_TRUE(EcmaString::StringsAreEqual(*result1_val, *str_handle)); @@ -811,7 +811,7 @@ TEST_F(BuiltinsDateTest, ToString) TEST_F(BuiltinsDateTest, ToTimeString) { int localMin = 0; - CString localTime; + PandaString localTime; JSHandle jsDate = JSDateCreateTest(thread); auto ecmaRuntimeCallInfo = CreateAndSetRuntimeCallInfo(thread, 4, jsDate.GetTaggedValue()); @@ -823,7 +823,7 @@ TEST_F(BuiltinsDateTest, ToTimeString) JSTaggedValue result1 = BuiltinsDate::ToTimeString(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result1.IsString()); JSHandle result1_val(thread, reinterpret_cast(result1.GetRawData())); - CString str = "18:10:06 GMT" + localTime; + PandaString str = "18:10:06 GMT" + localTime; JSHandle str_handle = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str); ASSERT_TRUE(EcmaString::StringsAreEqual(*result1_val, *str_handle)); diff --git a/tests/runtime/builtins/builtins_json_test.cpp b/tests/runtime/builtins/builtins_json_test.cpp index 97502ca11becb80b1c95e8b664cb173e43cade65..be612c9e57daf80e3e00056e1a80363cb9494fe0 100644 --- a/tests/runtime/builtins/builtins_json_test.cpp +++ b/tests/runtime/builtins/builtins_json_test.cpp @@ -113,7 +113,7 @@ public: }; }; -JSTaggedValue CreateBuiltinJSObject1(JSThread *thread, const CString keyCStr) +JSTaggedValue CreateBuiltinJSObject1(JSThread *thread, const PandaString keyCStr) { EcmaVM *ecmaVM = thread->GetEcmaVM(); JSHandle globalEnv = ecmaVM->GetGlobalEnv(); @@ -127,12 +127,12 @@ JSTaggedValue CreateBuiltinJSObject1(JSThread *thread, const CString keyCStr) JSHandle value(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, JSHandle(jsobject), key, value); - CString str2 = "y"; + PandaString str2 = "y"; JSHandle key2(factory->NewFromCanBeCompressString(str2)); JSHandle value2(thread, JSTaggedValue(2.5)); // 2.5 : test case JSObject::SetProperty(thread, JSHandle(jsobject), key2, value2); - CString str3 = "z"; + PandaString str3 = "z"; JSHandle key3(factory->NewFromCanBeCompressString(str3)); JSHandle value3(factory->NewFromCanBeCompressString("abc")); JSObject::SetProperty(thread, JSHandle(jsobject), key3, value3); diff --git a/tests/runtime/builtins/builtins_number_test.cpp b/tests/runtime/builtins/builtins_number_test.cpp index ac964aca77e20840b57fc0f59e93c42374bc25ec..4adb48fada324636f50721c4b04d793dbedca989 100644 --- a/tests/runtime/builtins/builtins_number_test.cpp +++ b/tests/runtime/builtins/builtins_number_test.cpp @@ -224,7 +224,7 @@ TEST_F(BuiltinsNumberTest, ToString) ASSERT_TRUE(result.IsString()); JSHandle res(thread, reinterpret_cast(result.GetRawData())); JSHandle correctResult = factory->NewFromCanBeCompressString("234.312256641535441"); - CVector test(res->GetLength() + 1); + PandaVector test(res->GetLength() + 1); res->CopyDataUtf8(test.data(), res->GetLength()); ASSERT_TRUE(EcmaString::StringsAreEqual(*res, *correctResult)); } @@ -250,7 +250,7 @@ TEST_F(BuiltinsNumberTest, IsExponential) ASSERT_TRUE(result.IsString()); JSHandle res(thread, reinterpret_cast(result.GetRawData())); JSHandle correctResult = factory->NewFromCanBeCompressString("1.23456e+2"); - CVector test(res->GetLength() + 1); + PandaVector test(res->GetLength() + 1); res->CopyDataUtf8(test.data(), res->GetLength()); ASSERT_TRUE(EcmaString::StringsAreEqual(*res, *correctResult)); } @@ -324,7 +324,7 @@ TEST_F(BuiltinsNumberTest, ToFixed2) ASSERT_TRUE(result.IsString()); JSHandle res(thread, reinterpret_cast(result.GetRawData())); JSHandle correctResult = factory->NewFromCanBeCompressString("1e+21"); - CVector test(res->GetLength() + 1); + PandaVector test(res->GetLength() + 1); res->CopyDataUtf8(test.data(), res->GetLength()); std::cout << test.data(); ASSERT_TRUE(EcmaString::StringsAreEqual(*res, *correctResult)); diff --git a/tests/runtime/builtins/builtins_object_test.cpp b/tests/runtime/builtins/builtins_object_test.cpp index 1dea4d5cccfeed4ae2a605ea14c2f2ed9a53528a..fbe6c908dfdb61c5bf6bcaac39b0deca3447088a 100644 --- a/tests/runtime/builtins/builtins_object_test.cpp +++ b/tests/runtime/builtins/builtins_object_test.cpp @@ -60,7 +60,7 @@ public: JSThread *thread {nullptr}; }; -JSTaggedValue CreateBuiltinJSObject(JSThread *thread, const CString keyCStr) +JSTaggedValue CreateBuiltinJSObject(JSThread *thread, const PandaString keyCStr) { EcmaVM *ecmaVM = thread->GetEcmaVM(); JSHandle globalEnv = ecmaVM->GetGlobalEnv(); @@ -967,7 +967,7 @@ TEST_F(BuiltinsObjectTest, Values) TEST_F(BuiltinsObjectTest, HasOwnProperty) { JSHandle obj(thread, CreateBuiltinJSObject(thread, "x")); - CString keyCStr = "x"; + PandaString keyCStr = "x"; JSHandle keyString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(&keyCStr[0]); JSHandle key(keyString); diff --git a/tests/runtime/builtins/builtins_typedarray_test.cpp b/tests/runtime/builtins/builtins_typedarray_test.cpp index 2258f94c927379aec8ca63fe7f8874a7e50836b8..dd640955062e97f5c00b965ca2a6ebe706cd5f8c 100644 --- a/tests/runtime/builtins/builtins_typedarray_test.cpp +++ b/tests/runtime/builtins/builtins_typedarray_test.cpp @@ -173,7 +173,7 @@ protected: }; }; -JSTaggedValue CreateBuiltinsJSObject(JSThread *thread, const CString keyCStr) +JSTaggedValue CreateBuiltinsJSObject(JSThread *thread, const PandaString keyCStr) { auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); diff --git a/tests/runtime/common/assert_scope_test.cpp b/tests/runtime/common/assert_scope_test.cpp deleted file mode 100644 index 9f984fe7bef96553cf1fdbadf6f721948659b766..0000000000000000000000000000000000000000 --- a/tests/runtime/common/assert_scope_test.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "gtest/gtest.h" -#include "plugins/ecmascript/runtime/mem/assert_scope-inl.h" - -using namespace panda::ecmascript; - -namespace panda::test { -class AssertScopeTest : public testing::Test { -public: - void SetUp() override {} - - void TearDown() override {} -}; - -TEST_F(AssertScopeTest, AssertScopeChecker) -{ -#if !defined(NDEBUG) - { - EXPECT_TRUE(AllowHeapAlloc::IsAllowed()); - EXPECT_TRUE(AllowGarbageCollection::IsAllowed()); - [[maybe_unused]] DisallowGarbageCollection no_gc; // set dis-allow gc - { - [[maybe_unused]] AllowGarbageCollection allow_gc; // set allow gc - EXPECT_TRUE(AllowGarbageCollection::IsAllowed()); - - [[maybe_unused]] DisAllowHeapAlloc no_heap_alloc; // set dis-allow alloc - { - [[maybe_unused]] AllowHeapAlloc heap_alloc; // set allow alloc - EXPECT_TRUE(AllowHeapAlloc::IsAllowed()); - } - EXPECT_FALSE(AllowHeapAlloc::IsAllowed()); - } - // allow alloc - EXPECT_TRUE(AllowHeapAlloc::IsAllowed()); - // dis-allow gc - EXPECT_FALSE(AllowGarbageCollection::IsAllowed()); - } - // allow gc - EXPECT_TRUE(AllowGarbageCollection::IsAllowed()); -#endif - EXPECT_TRUE(AllowHeapAlloc::IsAllowed()); - EXPECT_TRUE(AllowGarbageCollection::IsAllowed()); -} - -} // namespace panda::test diff --git a/tests/runtime/common/concurrent_marking_test.cpp b/tests/runtime/common/concurrent_marking_test.cpp deleted file mode 100644 index 5baafc23ba0caf4439a51a7733d77d14f1ea4795..0000000000000000000000000000000000000000 --- a/tests/runtime/common/concurrent_marking_test.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/tests/runtime/common/test_helper.h" - -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/global_env.h" -#include "plugins/ecmascript/runtime/js_handle.h" -#include "plugins/ecmascript/runtime/mem/clock_scope.h" -#include "plugins/ecmascript/runtime/mem/verification.h" - -using namespace panda::ecmascript; - -namespace panda::test { -class ConcurrentMarkingTest : public testing::Test { -public: - static void SetUpTestCase() - { - GTEST_LOG_(INFO) << "SetUpTestCase"; - } - - static void TearDownTestCase() - { - GTEST_LOG_(INFO) << "TearDownCase"; - } - - void SetUp() override - { - RuntimeOptions options; - options.SetShouldLoadBootPandaFiles(false); - options.SetShouldInitializeIntrinsics(false); - options.SetBootClassSpaces({"ecmascript"}); - options.SetRuntimeType("ecmascript"); - static EcmaLanguageContext lcEcma; - [[maybe_unused]] bool success = Runtime::Create(options, {&lcEcma}); - ASSERT_TRUE(success) << "Cannot create Runtime"; - instance = Runtime::GetCurrent()->GetPandaVM(); - ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM"; - thread = EcmaVM::Cast(instance)->GetJSThread(); - scope = new EcmaHandleScope(thread); - EcmaVM::Cast(instance)->SetEnableForceGC(false); - auto heap = const_cast(thread->GetEcmaVM()->GetHeap()); - heap->SetConcurrentMarkingEnable(true); - } - - void TearDown() override - { - TestHelper::DestroyEcmaVMWithScope(instance, scope); - } - - JSHandle CreateTaggedArray(uint32_t length, JSTaggedValue initVal, MemSpaceType spaceType) - { - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - return factory->NewTaggedArray(length, initVal, spaceType); - } - - PandaVM *instance {nullptr}; - ecmascript::EcmaHandleScope *scope {nullptr}; - JSThread *thread {nullptr}; -}; - -TEST_F(ConcurrentMarkingTest, PerformanceWithConcurrentMarking) -{ - uint32_t rootLength = 1024; - JSHandle rootArray = - CreateTaggedArray(rootLength, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE); - for (uint32_t i = 0; i < rootLength; i++) { - uint32_t subArrayLength = 1024; - auto array = CreateTaggedArray(subArrayLength, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE); - rootArray->Set(thread, i, array); - } - auto heap = const_cast(thread->GetEcmaVM()->GetHeap()); - heap->TriggerConcurrentMarking(); // concurrent mark - for (uint32_t i = 0; i < rootLength; i++) { - uint32_t subArrayLength = 1024; - auto array = CreateTaggedArray(subArrayLength, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE); - rootArray->Set(thread, i, array); - } - heap->CollectGarbage(TriggerGCType::OLD_GC); -} - -TEST_F(ConcurrentMarkingTest, PerformanceWithoutConcurrentMarking) -{ - uint32_t rootLength = 1024; - JSHandle rootArray = - CreateTaggedArray(rootLength, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE); - for (uint32_t i = 0; i < rootLength; i++) { - uint32_t subArrayLength = 1024; - auto array = CreateTaggedArray(subArrayLength, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE); - rootArray->Set(thread, i, array); - } - auto heap = const_cast(thread->GetEcmaVM()->GetHeap()); - for (uint32_t i = 0; i < rootLength; i++) { - uint32_t subArrayLength = 1024; - auto array = CreateTaggedArray(subArrayLength, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE); - rootArray->Set(thread, i, array); - } - heap->CollectGarbage(TriggerGCType::OLD_GC); -} -} // namespace panda::test diff --git a/tests/runtime/common/concurrent_sweep_test.cpp b/tests/runtime/common/concurrent_sweep_test.cpp index 6bb531d80ad061f7089ab6e7b8f23f91891d389d..6fe66a394cbd7e8196270d6193d0d1912f70bd7a 100644 --- a/tests/runtime/common/concurrent_sweep_test.cpp +++ b/tests/runtime/common/concurrent_sweep_test.cpp @@ -55,7 +55,7 @@ TEST_F(ConcurrentSweepTest, ConcurrentSweep) const uint8_t *utf8 = reinterpret_cast("test"); JSHandle test1(thread, EcmaString::CreateFromUtf8(utf8, 4, vm, false)); if (vm->IsInitialized()) { - vm->CollectGarbage(ecmascript::TriggerGCType::OLD_GC); + vm->CollectGarbage(); } JSHandle test2(thread, EcmaString::CreateFromUtf8(utf8, 4, vm, false)); ASSERT_EQ(test1->GetLength(), 4); diff --git a/tests/runtime/common/dump_test.cpp b/tests/runtime/common/dump_test.cpp deleted file mode 100644 index 84f905e7a939300ac1ac33aa6e6848a0c32491d3..0000000000000000000000000000000000000000 --- a/tests/runtime/common/dump_test.cpp +++ /dev/null @@ -1,672 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "gtest/gtest.h" -#include "test_helper.h" - -#include "plugins/ecmascript/runtime/accessor_data.h" -#include "plugins/ecmascript/runtime/class_info_extractor.h" -#include "plugins/ecmascript/runtime/class_linker/program_object-inl.h" -#include "plugins/ecmascript/runtime/ecma_module.h" -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/global_dictionary-inl.h" -#include "plugins/ecmascript/runtime/global_env.h" -#include "plugins/ecmascript/runtime/hprof/heap_profiler.h" -#include "plugins/ecmascript/runtime/hprof/heap_profiler_interface.h" -#include "plugins/ecmascript/runtime/hprof/heap_snapshot.h" -#include "plugins/ecmascript/runtime/hprof/heap_snapshot_json_serializer.h" -#include "plugins/ecmascript/runtime/hprof/string_hashmap.h" -#include "plugins/ecmascript/runtime/ic/ic_handler.h" -#include "plugins/ecmascript/runtime/ic/property_box.h" -#include "plugins/ecmascript/runtime/ic/proto_change_details.h" -#include "plugins/ecmascript/runtime/jobs/micro_job_queue.h" -#include "plugins/ecmascript/runtime/jobs/pending_job.h" -#include "plugins/ecmascript/runtime/js_arguments.h" -#include "plugins/ecmascript/runtime/js_array.h" -#include "plugins/ecmascript/runtime/js_arraylist.h" -#include "plugins/ecmascript/runtime/js_array_iterator.h" -#include "plugins/ecmascript/runtime/js_arraybuffer.h" -#include "plugins/ecmascript/runtime/js_async_from_sync_iterator_object.h" -#include "plugins/ecmascript/runtime/js_async_function.h" -#include "plugins/ecmascript/runtime/js_async_generator_object.h" -#include "plugins/ecmascript/runtime/js_collator.h" -#include "plugins/ecmascript/runtime/js_dataview.h" -#include "plugins/ecmascript/runtime/js_date.h" -#include "plugins/ecmascript/runtime/js_date_time_format.h" -#include "plugins/ecmascript/runtime/js_for_in_iterator.h" -#include "plugins/ecmascript/runtime/js_function.h" -#include "plugins/ecmascript/runtime/js_function_extra_info.h" -#include "plugins/ecmascript/runtime/js_generator_object.h" -#include "plugins/ecmascript/runtime/js_global_object.h" -#include "plugins/ecmascript/runtime/js_handle.h" -#include "plugins/ecmascript/runtime/js_intl.h" -#include "plugins/ecmascript/runtime/js_locale.h" -#include "plugins/ecmascript/runtime/js_map.h" -#include "plugins/ecmascript/runtime/js_map_iterator.h" -#include "plugins/ecmascript/runtime/js_number_format.h" -#include "plugins/ecmascript/runtime/js_object-inl.h" -#include "plugins/ecmascript/runtime/js_plural_rules.h" -#include "plugins/ecmascript/runtime/js_primitive_ref.h" -#include "plugins/ecmascript/runtime/js_promise.h" -#include "plugins/ecmascript/runtime/js_realm.h" -#include "plugins/ecmascript/runtime/js_regexp.h" -#include "plugins/ecmascript/runtime/js_relative_time_format.h" -#include "plugins/ecmascript/runtime/js_set.h" -#include "plugins/ecmascript/runtime/js_set_iterator.h" -#include "plugins/ecmascript/runtime/js_string_iterator.h" -#include "plugins/ecmascript/runtime/js_tagged_number.h" -#include "plugins/ecmascript/runtime/js_tagged_value-inl.h" -#include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/js_typed_array.h" -#include "plugins/ecmascript/runtime/js_weak_container.h" -#include "plugins/ecmascript/runtime/layout_info-inl.h" -#include "plugins/ecmascript/runtime/lexical_env.h" -#include "plugins/ecmascript/runtime/linked_hash_table-inl.h" -#include "plugins/ecmascript/runtime/mem/assert_scope-inl.h" -#include "plugins/ecmascript/runtime/mem/c_containers.h" -#include "plugins/ecmascript/runtime/mem/machine_code.h" -#include "plugins/ecmascript/runtime/object_factory.h" -#include "plugins/ecmascript/runtime/tagged_array.h" -#include "plugins/ecmascript/runtime/tagged_dictionary.h" -#include "plugins/ecmascript/runtime/template_map.h" -#include "plugins/ecmascript/runtime/transitions_dictionary.h" - -using namespace panda::coretypes; -using namespace panda::ecmascript; - -namespace panda::test { -class EcmaDumpTest : public testing::Test { -public: - static void SetUpTestCase() - { - GTEST_LOG_(INFO) << "SetUpTestCase"; - } - - static void TearDownTestCase() - { - GTEST_LOG_(INFO) << "TearDownCase"; - } - - void SetUp() override - { - TestHelper::CreateEcmaVMWithScope(instance, thread, scope); - } - - void TearDown() override - { - TestHelper::DestroyEcmaVMWithScope(instance, scope); - } - - PandaVM *instance {nullptr}; - ecmascript::EcmaHandleScope *scope {nullptr}; - JSThread *thread {nullptr}; -}; - -#ifndef NDEBUG -TEST_F(EcmaDumpTest, Dump) -{ - JSTaggedValue value1(100); - value1.D(); - - JSTaggedValue value2(100.0); - JSTaggedValue::DV(value2.GetRawData()); - - JSTaggedValue::Undefined().D(); - JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); - env.Dump(); - - JSHandle objFunc(env->GetObjectFunction()); - objFunc.Dump(); -} -#endif // #ifndef NDEBUG - -static JSHandle NewJSMap(JSThread *thread, ObjectFactory *factory, JSHandle proto) -{ - JSHandle mapClass = factory->NewEcmaDynClass(JSMap::SIZE, JSType::JS_MAP, proto); - JSHandle jsMap = JSHandle::Cast(factory->NewJSObject(mapClass)); - JSHandle linkedMap(LinkedHashMap::Create(thread)); - jsMap->SetLinkedMap(thread, linkedMap); - return jsMap; -} - -static JSHandle NewJSSet(JSThread *thread, ObjectFactory *factory, JSHandle proto) -{ - JSHandle setClass = factory->NewEcmaDynClass(JSSet::SIZE, JSType::JS_SET, proto); - JSHandle jsSet = JSHandle::Cast(factory->NewJSObject(setClass)); - JSHandle linkedSet(LinkedHashSet::Create(thread)); - jsSet->SetLinkedSet(thread, linkedSet); - return jsSet; -} - -static JSHandle NewJSObject(JSThread *thread, ObjectFactory *factory, JSHandle globalEnv) -{ - JSFunction *jsFunc = globalEnv->GetObjectFunction().GetObject(); - JSHandle jsFunc1(thread, jsFunc); - JSHandle jsObj = factory->NewJSObjectByConstructor(JSHandle(jsFunc1), jsFunc1); - return jsObj; -} - -TEST_F(EcmaDumpTest, HeapProfileDump) -{ - [[maybe_unused]] ecmascript::EcmaHandleScope scope_nested(thread); - auto factory = thread->GetEcmaVM()->GetFactory(); - auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); - auto globalConst = const_cast(thread->GlobalConstants()); - JSHandle proto = globalEnv->GetFunctionPrototype(); - std::vector> snapshotVector; - -#define DUMP_FOR_HANDLE(dumpHandle) \ - dumpHandle.GetTaggedValue().D(); \ - dumpHandle.GetTaggedValue().DumpForSnapshot(thread, snapshotVector); - -#define NEW_OBJECT_AND_DUMP(ClassName, TypeName) \ - JSHandle class##ClassName = factory->NewEcmaDynClass(ClassName::SIZE, JSType::TypeName, proto); \ - JSHandle object##ClassName = factory->NewJSObject(class##ClassName); \ - object##ClassName.GetTaggedValue().D(); \ - object##ClassName.GetTaggedValue().DumpForSnapshot(thread, snapshotVector); - - for (JSType type = JSType::JS_OBJECT; type <= JSType::JS_TYPE_LAST; type = JSType(static_cast(type) + 1)) { - switch (type) { - case JSType::JS_ERROR: - case JSType::JS_EVAL_ERROR: - case JSType::JS_RANGE_ERROR: - case JSType::JS_TYPE_ERROR: - case JSType::JS_REFERENCE_ERROR: - case JSType::JS_URI_ERROR: - case JSType::JS_SYNTAX_ERROR: - case JSType::JS_OBJECT: { - CHECK_DUMP_FILEDS(ECMAObject::SIZE, JSObject::SIZE, 2) - JSHandle jsObj = NewJSObject(thread, factory, globalEnv); - DUMP_FOR_HANDLE(jsObj) - break; - } - case JSType::JS_REALM: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSRealm::SIZE, 2) - JSHandle jsRealm = factory->NewJSRealm(); - DUMP_FOR_HANDLE(jsRealm) - break; - } - case JSType::JS_FUNCTION_BASE: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSFunctionBase::SIZE, 1) - break; - } - case JSType::JS_FUNCTION: { - CHECK_DUMP_FILEDS(JSFunctionBase::SIZE, JSFunction::SIZE, 7) - JSHandle jsFunc = globalEnv->GetFunctionFunction(); - DUMP_FOR_HANDLE(jsFunc) - break; - } - case JSType::JS_PROXY_REVOC_FUNCTION: { - CHECK_DUMP_FILEDS(JSFunction::SIZE, JSProxyRevocFunction::SIZE, 1) - JSHandle proxyRevocClass = JSHandle::Cast(globalEnv->GetProxyRevocFunctionClass()); - JSHandle proxyRevocFunc = factory->NewJSObject(proxyRevocClass); - DUMP_FOR_HANDLE(proxyRevocFunc) - break; - } - case JSType::JS_PROMISE_REACTIONS_FUNCTION: { - CHECK_DUMP_FILEDS(JSFunction::SIZE, JSPromiseReactionsFunction::SIZE, 2) - JSHandle promiseReactClass = - JSHandle::Cast(globalEnv->GetPromiseReactionFunctionClass()); - JSHandle promiseReactFunc = factory->NewJSObject(promiseReactClass); - DUMP_FOR_HANDLE(promiseReactFunc) - break; - } - case JSType::JS_PROMISE_EXECUTOR_FUNCTION: { - CHECK_DUMP_FILEDS(JSFunction::SIZE, JSPromiseExecutorFunction::SIZE, 1) - JSHandle promiseExeClass = - JSHandle::Cast(globalEnv->GetPromiseExecutorFunctionClass()); - JSHandle promiseExeFunc = factory->NewJSObject(promiseExeClass); - DUMP_FOR_HANDLE(promiseExeFunc) - break; - } - case JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION: { - CHECK_DUMP_FILEDS(JSFunction::SIZE, JSPromiseAllResolveElementFunction::SIZE, 5) - JSHandle promiseAllClass = - JSHandle::Cast(globalEnv->GetPromiseAllResolveElementFunctionClass()); - JSHandle promiseAllFunc = factory->NewJSObject(promiseAllClass); - DUMP_FOR_HANDLE(promiseAllFunc) - break; - } - case JSType::JS_GENERATOR_FUNCTION: { - CHECK_DUMP_FILEDS(JSFunction::SIZE, JSGeneratorFunction::SIZE, 0) - break; - } - case JSType::JS_ASYNC_FUNCTION: { - CHECK_DUMP_FILEDS(JSFunction::SIZE, JSAsyncFunction::SIZE, 0) - break; - } - case JSType::JS_ASYNC_GENERATOR_FUNCTION: { - CHECK_DUMP_FILEDS(JSFunction::SIZE, JSAsyncGeneratorFunction::SIZE, 0) - break; - } - case JSType::JS_INTL_BOUND_FUNCTION: { - CHECK_DUMP_FILEDS(JSFunction::SIZE, JSIntlBoundFunction::SIZE, 3) - JSHandle intlBoundFunc = factory->NewJSIntlBoundFunction(); - DUMP_FOR_HANDLE(intlBoundFunc) - break; - } - case JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION: { - CHECK_DUMP_FILEDS(JSFunction::SIZE, JSAsyncAwaitStatusFunction::SIZE, 1) - JSHandle asyncAwaitFunc = factory->NewJSAsyncAwaitStatusFunction(); - DUMP_FOR_HANDLE(asyncAwaitFunc) - break; - } - case JSType::JS_ASYNC_GENERATOR_RESOLVE_NEXT_FUNCTION: { - CHECK_DUMP_FILEDS(JSFunction::SIZE, JSAsyncGeneratorResolveNextFunction::SIZE, 1) - JSHandle asyncGenResolveNextFunc = - factory->NewJSAsyncGeneratorResolveNextFunction(); - DUMP_FOR_HANDLE(asyncGenResolveNextFunc) - break; - } - case JSType::JS_ASYNC_FROM_SYNC_ITERATOR_VALUE_UNWRAP_FUNCTION: { - CHECK_DUMP_FILEDS(JSFunction::SIZE, JSAsyncFromSyncIteratorValueUnwrapFunction::SIZE, 2) - JSHandle asyncFromSyncIteratorValueUnwrapFunction = - factory->NewJSAsyncFromSyncIteratorValueUnwrapFunction(); - DUMP_FOR_HANDLE(asyncFromSyncIteratorValueUnwrapFunction) - break; - } - case JSType::JS_BOUND_FUNCTION: { - CHECK_DUMP_FILEDS(JSFunctionBase::SIZE, JSBoundFunction::SIZE, 3) - NEW_OBJECT_AND_DUMP(JSBoundFunction, JS_BOUND_FUNCTION) - break; - } - case JSType::JS_REG_EXP: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSRegExp::SIZE, 5) - NEW_OBJECT_AND_DUMP(JSRegExp, JS_REG_EXP) - break; - } - case JSType::JS_SET: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSSet::SIZE, 1) - JSHandle jsSet = NewJSSet(thread, factory, proto); - DUMP_FOR_HANDLE(jsSet) - break; - } - case JSType::JS_MAP: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSMap::SIZE, 1) - JSHandle jsMap = NewJSMap(thread, factory, proto); - DUMP_FOR_HANDLE(jsMap) - break; - } - case JSType::JS_WEAK_MAP: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSWeakMap::SIZE, 1) - JSHandle weakMapClass = factory->NewEcmaDynClass(JSWeakMap::SIZE, JSType::JS_WEAK_MAP, proto); - JSHandle jsWeakMap = JSHandle::Cast(factory->NewJSObject(weakMapClass)); - JSHandle weakLinkedMap(LinkedHashMap::Create(thread)); - jsWeakMap->SetLinkedMap(thread, weakLinkedMap); - DUMP_FOR_HANDLE(jsWeakMap) - break; - } - case JSType::JS_WEAK_SET: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSWeakSet::SIZE, 1) - JSHandle weakSetClass = factory->NewEcmaDynClass(JSWeakSet::SIZE, JSType::JS_WEAK_SET, proto); - JSHandle jsWeakSet = JSHandle::Cast(factory->NewJSObject(weakSetClass)); - JSHandle weakLinkedSet(LinkedHashSet::Create(thread)); - jsWeakSet->SetLinkedSet(thread, weakLinkedSet); - DUMP_FOR_HANDLE(jsWeakSet) - break; - } - case JSType::JS_DATE: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSDate::SIZE, 2) - JSHandle dateClass = factory->NewEcmaDynClass(JSDate::SIZE, JSType::JS_DATE, proto); - JSHandle date = JSHandle::Cast(factory->NewJSObject(dateClass)); - date->SetTimeValue(thread, JSTaggedValue(0.0)); - date->SetLocalOffset(thread, JSTaggedValue(0.0)); - DUMP_FOR_HANDLE(date) - break; - } - case JSType::JS_ITERATOR: - // JS Iterate is a tool class, so we don't need to check it. - break; - case JSType::JS_FORIN_ITERATOR: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSForInIterator::SIZE, 4) - JSHandle array(thread, factory->NewJSArray().GetTaggedValue()); - JSHandle forInIter = factory->NewJSForinIterator(array); - DUMP_FOR_HANDLE(forInIter) - break; - } - case JSType::JS_MAP_ITERATOR: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSMapIterator::SIZE, 3) - JSHandle jsMapIter = - factory->NewJSMapIterator(NewJSMap(thread, factory, proto), IterationKind::KEY); - DUMP_FOR_HANDLE(jsMapIter) - break; - } - case JSType::JS_SET_ITERATOR: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSSetIterator::SIZE, 3) - JSHandle jsSetIter = - factory->NewJSSetIterator(NewJSSet(thread, factory, proto), IterationKind::KEY); - DUMP_FOR_HANDLE(jsSetIter) - break; - } - case JSType::JS_ARRAY_ITERATOR: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSArrayIterator::SIZE, 3) - JSHandle arrayIter = - factory->NewJSArrayIterator(JSHandle::Cast(factory->NewJSArray()), IterationKind::KEY); - DUMP_FOR_HANDLE(arrayIter) - break; - } - case JSType::JS_STRING_ITERATOR: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSStringIterator::SIZE, 2) - JSHandle stringIter = globalEnv->GetStringIterator(); - DUMP_FOR_HANDLE(stringIter) - break; - } - case JSType::JS_INTL: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSIntl::SIZE, 1) - NEW_OBJECT_AND_DUMP(JSIntl, JS_INTL) - break; - } - case JSType::JS_LOCALE: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSLocale::SIZE, 1) - NEW_OBJECT_AND_DUMP(JSLocale, JS_LOCALE) - break; - } - case JSType::JS_DATE_TIME_FORMAT: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSDateTimeFormat::SIZE, 11) - NEW_OBJECT_AND_DUMP(JSDateTimeFormat, JS_DATE_TIME_FORMAT) - break; - } - case JSType::JS_RELATIVE_TIME_FORMAT: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSRelativeTimeFormat::SIZE, 7) - NEW_OBJECT_AND_DUMP(JSRelativeTimeFormat, JS_RELATIVE_TIME_FORMAT) - break; - } - case JSType::JS_NUMBER_FORMAT: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSNumberFormat::SIZE, 20) - NEW_OBJECT_AND_DUMP(JSNumberFormat, JS_NUMBER_FORMAT) - break; - } - case JSType::JS_COLLATOR: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSCollator::SIZE, 9) - NEW_OBJECT_AND_DUMP(JSCollator, JS_COLLATOR) - break; - } - case JSType::JS_PLURAL_RULES: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSPluralRules::SIZE, 11) - NEW_OBJECT_AND_DUMP(JSPluralRules, JS_PLURAL_RULES) - break; - } - case JSType::JS_ARRAY_BUFFER: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSArrayBuffer::SIZE, 3) - NEW_OBJECT_AND_DUMP(JSArrayBuffer, JS_ARRAY_BUFFER) - break; - } - case JSType::JS_PROMISE: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSPromise::SIZE, 5) - NEW_OBJECT_AND_DUMP(JSPromise, JS_PROMISE) - break; - } - case JSType::JS_DATA_VIEW: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSDataView::SIZE, 4) - NEW_OBJECT_AND_DUMP(JSDataView, JS_DATA_VIEW) - break; - } - case JSType::JS_ARGUMENTS: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSArguments::SIZE, 1) - NEW_OBJECT_AND_DUMP(JSArguments, JS_ARGUMENTS) - break; - } - case JSType::JS_GENERATOR_OBJECT: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSGeneratorObject::SIZE, 4) - NEW_OBJECT_AND_DUMP(JSGeneratorObject, JS_GENERATOR_OBJECT) - break; - } - case JSType::JS_ASYNC_FROM_SYNC_ITERATOR_OBJECT: { - CHECK_DUMP_FILEDS(JSObject::SIZE, ecmascript::JSAsyncFromSyncIteratorObject::SIZE, 2) - JSHandle asyncFromSyncIteratorObject = - factory->NewJSAsyncFromSyncIteratorObject(); - DUMP_FOR_HANDLE(asyncFromSyncIteratorObject) - break; - } - case JSType::JS_ASYNC_FUNC_OBJECT: { - CHECK_DUMP_FILEDS(JSGeneratorObject::SIZE, JSAsyncFuncObject::SIZE, 1) - JSHandle asyncFuncObject = factory->NewJSAsyncFuncObject(); - DUMP_FOR_HANDLE(asyncFuncObject) - break; - } - case JSType::JS_ASYNC_GENERATOR_OBJECT: { - CHECK_DUMP_FILEDS(ecmascript::JSAsyncFuncObject::SIZE, ecmascript::JSAsyncGeneratorObject::SIZE, 1) - JSHandle asyncGenObject = factory->NewJSAsyncGeneratorObject(); - DUMP_FOR_HANDLE(asyncGenObject) - break; - } - case JSType::JS_ARRAY: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSArray::SIZE, 1) - JSHandle jsArray = factory->NewJSArray(); - DUMP_FOR_HANDLE(jsArray) - break; - } - case JSType::JS_TYPED_ARRAY: - case JSType::JS_INT8_ARRAY: - case JSType::JS_UINT8_ARRAY: - case JSType::JS_UINT8_CLAMPED_ARRAY: - case JSType::JS_INT16_ARRAY: - case JSType::JS_UINT16_ARRAY: - case JSType::JS_INT32_ARRAY: - case JSType::JS_UINT32_ARRAY: - case JSType::JS_FLOAT32_ARRAY: - case JSType::JS_FLOAT64_ARRAY: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSTypedArray::SIZE, 5) - NEW_OBJECT_AND_DUMP(JSTypedArray, JS_TYPED_ARRAY) - break; - } - case JSType::JS_PRIMITIVE_REF: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSPrimitiveRef::SIZE, 1) - NEW_OBJECT_AND_DUMP(JSPrimitiveRef, JS_PRIMITIVE_REF) - break; - } - case JSType::JS_GLOBAL_OBJECT: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSGlobalObject::SIZE, 0) - JSHandle globalObject = globalEnv->GetJSGlobalObject(); - DUMP_FOR_HANDLE(globalObject) - break; - } - case JSType::JS_PROXY: { - CHECK_DUMP_FILEDS(ECMAObject::SIZE, JSProxy::SIZE, 3) - JSHandle emptyObj(thread, NewJSObject(thread, factory, globalEnv).GetTaggedValue()); - JSHandle proxy = factory->NewJSProxy(emptyObj, emptyObj); - DUMP_FOR_HANDLE(proxy) - break; - } - case JSType::HCLASS: { - CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), JSHClass::SIZE, 9) - JSHandle hclass = factory->NewEcmaDynClass(JSHClass::SIZE, JSType::HCLASS, proto); - DUMP_FOR_HANDLE(hclass) - break; - } - case JSType::STRING: { - DUMP_FOR_HANDLE(globalEnv->GetObjectFunction()) - break; - } - case JSType::TAGGED_ARRAY: { - JSHandle taggedArray = factory->NewTaggedArray(4); - DUMP_FOR_HANDLE(taggedArray) - break; - } - case JSType::TAGGED_DICTIONARY: { - JSHandle dict = factory->NewDictionaryArray(4); - DUMP_FOR_HANDLE(dict) - break; - } - case JSType::FREE_OBJECT_WITH_ONE_FIELD: - case JSType::FREE_OBJECT_WITH_NONE_FIELD: - case JSType::FREE_OBJECT_WITH_TWO_FIELD: { - break; - } - case JSType::JS_NATIVE_POINTER: { - break; - } - case JSType::GLOBAL_ENV: { - DUMP_FOR_HANDLE(globalEnv) - break; - } - case JSType::ACCESSOR_DATA: - case JSType::INTERNAL_ACCESSOR: { - CHECK_DUMP_FILEDS(Record::SIZE, AccessorData::SIZE, 2) - JSHandle accessor = factory->NewAccessorData(); - DUMP_FOR_HANDLE(accessor) - break; - } - case JSType::SYMBOL: { - CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), JSSymbol::SIZE, 3) - JSHandle symbol = factory->NewJSSymbol(); - DUMP_FOR_HANDLE(symbol) - break; - } - case JSType::JS_GENERATOR_CONTEXT: { - CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), GeneratorContext::SIZE, 7) - JSHandle genContext = factory->NewGeneratorContext(); - DUMP_FOR_HANDLE(genContext) - break; - } - case JSType::PROTOTYPE_HANDLER: { - CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), PrototypeHandler::SIZE, 3) - JSHandle protoHandler = factory->NewPrototypeHandler(); - DUMP_FOR_HANDLE(protoHandler) - break; - } - case JSType::TRANSITION_HANDLER: { - CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), TransitionHandler::SIZE, 2) - JSHandle transitionHandler = factory->NewTransitionHandler(); - DUMP_FOR_HANDLE(transitionHandler) - break; - } - case JSType::PROPERTY_BOX: { - CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), PropertyBox::SIZE, 1) - JSHandle PropertyBox = factory->NewPropertyBox(globalEnv->GetEmptyArray()); - DUMP_FOR_HANDLE(PropertyBox) - break; - } - case JSType::PROTO_CHANGE_MARKER: { - CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), ProtoChangeMarker::SIZE, 1) - JSHandle protoMaker = factory->NewProtoChangeMarker(); - DUMP_FOR_HANDLE(protoMaker) - break; - } - case JSType::PROTOTYPE_INFO: { - CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), ProtoChangeDetails::SIZE, 2) - JSHandle protoDetails = factory->NewProtoChangeDetails(); - DUMP_FOR_HANDLE(protoDetails) - break; - } - case JSType::TEMPLATE_MAP: { - JSHandle templateMap = globalEnv->GetTemplateMap(); - DUMP_FOR_HANDLE(templateMap) - break; - } - case JSType::PROGRAM: { - CHECK_DUMP_FILEDS(ECMAObject::SIZE, Program::SIZE, 5) - JSHandle program = factory->NewProgram(); - DUMP_FOR_HANDLE(program) - break; - } - case JSType::LEXICAL_FUNCTION: { - CHECK_DUMP_FILEDS(ECMAObject::SIZE, LexicalFunction::SIZE, 5) - // unused - break; - } - case JSType::PROMISE_CAPABILITY: { - CHECK_DUMP_FILEDS(Record::SIZE, PromiseCapability::SIZE, 3) - JSHandle promiseCapa = factory->NewPromiseCapability(); - DUMP_FOR_HANDLE(promiseCapa) - break; - } - case JSType::PROMISE_RECORD: { - CHECK_DUMP_FILEDS(Record::SIZE, PromiseRecord::SIZE, 1) - JSHandle promiseRecord = factory->NewPromiseRecord(); - DUMP_FOR_HANDLE(promiseRecord) - break; - } - case JSType::RESOLVING_FUNCTIONS_RECORD: { - CHECK_DUMP_FILEDS(Record::SIZE, ResolvingFunctionsRecord::SIZE, 2) - JSHandle ResolvingFunc = factory->NewResolvingFunctionsRecord(); - DUMP_FOR_HANDLE(ResolvingFunc) - break; - } - case JSType::PROMISE_REACTIONS: { - CHECK_DUMP_FILEDS(Record::SIZE, PromiseReaction::SIZE, 3) - JSHandle promiseReact = factory->NewPromiseReaction(); - DUMP_FOR_HANDLE(promiseReact) - break; - } - case JSType::PROMISE_ITERATOR_RECORD: { - CHECK_DUMP_FILEDS(Record::SIZE, PromiseIteratorRecord::SIZE, 2) - JSHandle emptyObj(thread, NewJSObject(thread, factory, globalEnv).GetTaggedValue()); - JSHandle promiseIter = factory->NewPromiseIteratorRecord(emptyObj, emptyObj); - DUMP_FOR_HANDLE(promiseIter) - break; - } - case JSType::MICRO_JOB_QUEUE: { - CHECK_DUMP_FILEDS(Record::SIZE, ecmascript::job::MicroJobQueue::SIZE, 2) - JSHandle microJob = factory->NewMicroJobQueue(); - DUMP_FOR_HANDLE(microJob) - break; - } - case JSType::PENDING_JOB: { - CHECK_DUMP_FILEDS(Record::SIZE, ecmascript::job::PendingJob::SIZE, 2) - JSHandle pendingClass(thread, - JSHClass::Cast(globalConst->GetPendingJobClass().GetTaggedObject())); - JSHandle pendingJob(thread, factory->NewDynObject(pendingClass)); - DUMP_FOR_HANDLE(pendingJob) - break; - } - case JSType::FUNCTION_EXTRA_INFO: { - CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), JSFunctionExtraInfo::SIZE, 2) - JSHandle funcExtraClass( - thread, JSHClass::Cast(globalConst->GetFunctionExtraInfoClass().GetTaggedObject())); - JSHandle funcInfo(thread, factory->NewDynObject(funcExtraClass)); - DUMP_FOR_HANDLE(funcInfo) - break; - } - case JSType::COMPLETION_RECORD: { - CHECK_DUMP_FILEDS(Record::SIZE, CompletionRecord::SIZE, 2) - JSHandle comRecord = factory->NewCompletionRecord(0, globalEnv->GetEmptyArray()); - DUMP_FOR_HANDLE(comRecord) - break; - } - case JSType::MACHINE_CODE_OBJECT: { - CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), MachineCode::DATA_OFFSET, 1) - JSHandle machineCode = factory->NewMachineCodeObject(16, nullptr); - DUMP_FOR_HANDLE(machineCode) - break; - } - case JSType::ECMA_MODULE: { - CHECK_DUMP_FILEDS(ECMAObject::SIZE, EcmaModule::SIZE, 1) - JSHandle ecmaModule = factory->NewEmptyEcmaModule(); - DUMP_FOR_HANDLE(ecmaModule) - break; - } - case JSType::CLASS_INFO_EXTRACTOR: { - CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), ClassInfoExtractor::SIZE, 10) - JSHandle classInfoExtractor = factory->NewClassInfoExtractor(nullptr); - DUMP_FOR_HANDLE(classInfoExtractor) - break; - } - case JSType::JS_QUEUE: - case JSType::JS_ARRAY_LIST: { - CHECK_DUMP_FILEDS(JSObject::SIZE, JSArrayList::SIZE, 1) - // unused - break; - } - default: - LOG_ECMA_MEM(ERROR) << "JSType " << static_cast(type) << " cannot be dumped."; - UNREACHABLE(); - break; - } - } -#undef NEW_OBJECT_AND_DUMP -#undef DUMP_FOR_HANDLE -} -} // namespace panda::test diff --git a/tests/runtime/common/ecma_module_test.cpp b/tests/runtime/common/ecma_module_test.cpp index 649169e6d086cfcf50474b47596e74edcc5a793e..ddc6874dfd4c17a18ef6e9151a724363b961beab 100644 --- a/tests/runtime/common/ecma_module_test.cpp +++ b/tests/runtime/common/ecma_module_test.cpp @@ -66,7 +66,7 @@ EcmaModule *EcmaModuleCreate(JSThread *thread) TEST_F(EcmaModuleTest, AddItem_001) { int numOfElementsDict = 4; - CString cStrItemName = "key1"; + PandaString cStrItemName = "key1"; int intItemValue = 1; JSHandle handleEcmaModule(thread, EcmaModuleCreate(thread)); JSHandle handleNameDict(NameDictionary::Create(thread, numOfElementsDict)); @@ -89,7 +89,7 @@ TEST_F(EcmaModuleTest, AddItem_001) */ TEST_F(EcmaModuleTest, AddItem_002) { - CString cStrItemName = "cStrItemName"; + PandaString cStrItemName = "cStrItemName"; int intItemValue = 1; JSHandle handleEcmaModule(thread, EcmaModuleCreate(thread)); JSHandle handleTagValItemName( @@ -114,7 +114,7 @@ TEST_F(EcmaModuleTest, RemoveItem) { ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory(); - CString cStrItemName = "cStrItemName"; + PandaString cStrItemName = "cStrItemName"; int intItemValue = 1; JSHandle handleEcmaModule(thread, EcmaModuleCreate(thread)); JSHandle handleTagValItemName(objFactory->NewFromCanBeCompressString(cStrItemName)); @@ -143,7 +143,7 @@ TEST_F(EcmaModuleTest, SetNameDictionary) int numOfElementsDict = 4; JSHandle handleNameDict(NameDictionary::Create(thread, numOfElementsDict)); JSHandle handleObjFunc = thread->GetEcmaVM()->GetGlobalEnv()->GetObjectFunction(); - CString keyArray1 = "hello1"; + PandaString keyArray1 = "hello1"; JSHandle stringKey1 = objFactory->NewFromCanBeCompressString(keyArray1); JSHandle key1(stringKey1); JSHandle value1( @@ -177,8 +177,8 @@ TEST_F(EcmaModuleTest, ModuleManager_AddModule) int numOfElementsDict1 = 4; int numOfElementsDict2 = 4; - CString cStrItemName1 = "cStrItemName1"; - CString cStrItemName2 = "cStrItemName2"; + PandaString cStrItemName1 = "cStrItemName1"; + PandaString cStrItemName2 = "cStrItemName2"; int intItemValue1 = 1; int intItemValue2 = 2; JSHandle handleNameDict1(NameDictionary::Create(thread, numOfElementsDict1)); @@ -292,9 +292,9 @@ TEST_F(EcmaModuleTest, ModuleManager_SetCurrentExportModuleName) std::string_view strViewNameEcmaModule1 = "NameEcmaModule1"; std::string_view strViewNameEcmaModule2 = "NameEcmaModule2"; moduleManager->SetCurrentExportModuleName(strViewNameEcmaModule1); - EXPECT_STREQ(moduleManager->GetCurrentExportModuleName().c_str(), CString(strViewNameEcmaModule1).c_str()); + EXPECT_STREQ(moduleManager->GetCurrentExportModuleName().c_str(), PandaString(strViewNameEcmaModule1).c_str()); moduleManager->SetCurrentExportModuleName(strViewNameEcmaModule2); - EXPECT_STREQ(moduleManager->GetCurrentExportModuleName().c_str(), CString(strViewNameEcmaModule2).c_str()); + EXPECT_STREQ(moduleManager->GetCurrentExportModuleName().c_str(), PandaString(strViewNameEcmaModule2).c_str()); } /* @@ -315,9 +315,9 @@ TEST_F(EcmaModuleTest, ModuleManager_GetPrevExportModuleName) std::string_view strViewNameEcmaModule3 = "NameEcmaModule3"; moduleManager->SetCurrentExportModuleName(strViewNameEcmaModule1); moduleManager->SetCurrentExportModuleName(strViewNameEcmaModule2); - EXPECT_STREQ(moduleManager->GetPrevExportModuleName().c_str(), CString(strViewNameEcmaModule1).c_str()); + EXPECT_STREQ(moduleManager->GetPrevExportModuleName().c_str(), PandaString(strViewNameEcmaModule1).c_str()); moduleManager->SetCurrentExportModuleName(strViewNameEcmaModule3); - EXPECT_STREQ(moduleManager->GetPrevExportModuleName().c_str(), CString(strViewNameEcmaModule2).c_str()); + EXPECT_STREQ(moduleManager->GetPrevExportModuleName().c_str(), PandaString(strViewNameEcmaModule2).c_str()); } /* @@ -340,11 +340,11 @@ TEST_F(EcmaModuleTest, ModuleManager_RestoreCurrentExportModuleName) moduleManager->SetCurrentExportModuleName(strViewNameEcmaModule1); moduleManager->SetCurrentExportModuleName(strViewNameEcmaModule2); moduleManager->SetCurrentExportModuleName(strViewNameEcmaModule3); - EXPECT_STREQ(moduleManager->GetCurrentExportModuleName().c_str(), CString(strViewNameEcmaModule3).c_str()); + EXPECT_STREQ(moduleManager->GetCurrentExportModuleName().c_str(), PandaString(strViewNameEcmaModule3).c_str()); moduleManager->RestoreCurrentExportModuleName(); - EXPECT_STREQ(moduleManager->GetCurrentExportModuleName().c_str(), CString(strViewNameEcmaModule2).c_str()); + EXPECT_STREQ(moduleManager->GetCurrentExportModuleName().c_str(), PandaString(strViewNameEcmaModule2).c_str()); moduleManager->RestoreCurrentExportModuleName(); - EXPECT_STREQ(moduleManager->GetCurrentExportModuleName().c_str(), CString(strViewNameEcmaModule1).c_str()); + EXPECT_STREQ(moduleManager->GetCurrentExportModuleName().c_str(), PandaString(strViewNameEcmaModule1).c_str()); } /* @@ -451,7 +451,7 @@ TEST_F(EcmaModuleTest, ModuleManager_CopyModule) moduleManager->SetCurrentExportModuleName(fileNameEcmaModuleCopyTo1); moduleManager->CopyModule(thread, handleTagValEcmaModuleCopyFrom1); JSHandle handleTagValEcmaModuleCopyTo1 = moduleManager->GetModule( - thread, JSHandle::Cast(objFactory->NewFromString(CString(fileNameEcmaModuleCopyTo1)))); + thread, JSHandle::Cast(objFactory->NewFromString(PandaString(fileNameEcmaModuleCopyTo1)))); EXPECT_EQ(intItemValue11, moduleManager->GetModuleItem(thread, handleTagValEcmaModuleCopyTo1, handleTagValItemName11)->GetNumber()); EXPECT_EQ(intItemValue12, @@ -460,7 +460,7 @@ TEST_F(EcmaModuleTest, ModuleManager_CopyModule) moduleManager->SetCurrentExportModuleName(fileNameEcmaModuleCopyTo2); moduleManager->CopyModule(thread, handleTagValEcmaModuleCopyFrom2); JSHandle handleTagValEcmaModuleCopyTo2 = moduleManager->GetModule( - thread, JSHandle::Cast(objFactory->NewFromString(CString(fileNameEcmaModuleCopyTo2)))); + thread, JSHandle::Cast(objFactory->NewFromString(PandaString(fileNameEcmaModuleCopyTo2)))); EXPECT_EQ(intItemValue11, moduleManager->GetModuleItem(thread, handleTagValEcmaModuleCopyTo1, handleTagValItemName11)->GetNumber()); EXPECT_EQ(intItemValue12, diff --git a/tests/runtime/common/ecma_string_test.cpp b/tests/runtime/common/ecma_string_test.cpp index 2013fa615bfb30ed9ac562464e4d3bf78bbf0ee8..0dc91ffc53f2bcefd8eb6672709ec447b751f6ac 100644 --- a/tests/runtime/common/ecma_string_test.cpp +++ b/tests/runtime/common/ecma_string_test.cpp @@ -1811,19 +1811,19 @@ TEST_F(EcmaStringTest, GetCString) uint32_t lengthEcmaStrU8 = sizeof(arrayU8) - 1; JSHandle handleEcmaStrU8(thread, EcmaString::CreateFromUtf8(&arrayU8[0], lengthEcmaStrU8, ecmaVMPtr, true)); - EXPECT_STREQ(CString(handleEcmaStrU8->GetCString().get()).c_str(), "abc"); + EXPECT_STREQ(PandaString(handleEcmaStrU8->GetCString().get()).c_str(), "abc"); uint16_t arrayU16Comp[] = {97, 98, 99}; uint32_t lengthEcmaStrU16Comp = sizeof(arrayU16Comp) / sizeof(arrayU16Comp[0]); JSHandle handleEcmaStrU16Comp( thread, EcmaString::CreateFromUtf16(&arrayU16Comp[0], lengthEcmaStrU16Comp, ecmaVMPtr, true)); - EXPECT_STREQ(CString(handleEcmaStrU16Comp->GetCString().get()).c_str(), "abc"); + EXPECT_STREQ(PandaString(handleEcmaStrU16Comp->GetCString().get()).c_str(), "abc"); uint16_t arrayU16NotComp[] = {97, 98, 99}; uint32_t lengthEcmaStrU16NotComp = sizeof(arrayU16NotComp) / sizeof(arrayU16NotComp[0]); JSHandle handleEcmaStrU16NotComp( thread, EcmaString::CreateFromUtf16(&arrayU16NotComp[0], lengthEcmaStrU16NotComp, ecmaVMPtr, false)); - EXPECT_STREQ(CString(handleEcmaStrU16NotComp->GetCString().get()).c_str(), "abc"); + EXPECT_STREQ(PandaString(handleEcmaStrU16NotComp->GetCString().get()).c_str(), "abc"); } /* diff --git a/tests/runtime/common/gc_test.cpp b/tests/runtime/common/gc_test.cpp deleted file mode 100644 index 8de8aa474eebd65d8d4180dfc4002c9dc6afc4c5..0000000000000000000000000000000000000000 --- a/tests/runtime/common/gc_test.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/mem/compress_collector.h" -#include "plugins/ecmascript/runtime/mem/semi_space_collector.h" -#include "plugins/ecmascript/runtime/object_factory.h" -#include "plugins/ecmascript/tests/runtime/common/test_helper.h" - -using namespace panda; - -using namespace panda::ecmascript; - -namespace panda::test { -class GCTest : public testing::Test { -public: - static void SetUpTestCase() - { - GTEST_LOG_(INFO) << "SetUpTestCase"; - } - - static void TearDownTestCase() - { - GTEST_LOG_(INFO) << "TearDownCase"; - } - - void SetUp() override - { - JSRuntimeOptions options; - options.SetShouldLoadBootPandaFiles(false); - options.SetShouldInitializeIntrinsics(false); - options.SetBootClassSpaces({"ecmascript"}); - options.SetRuntimeType("ecmascript"); - options.SetEnableParalledYoungGc(false); - static EcmaLanguageContext lcEcma; - [[maybe_unused]] bool success = Runtime::Create(options, {&lcEcma}); - ASSERT_TRUE(success) << "Cannot create Runtime"; - instance = Runtime::GetCurrent()->GetPandaVM(); - ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM"; - thread = EcmaVM::Cast(instance)->GetJSThread(); - scope = new EcmaHandleScope(thread); - } - - void TearDown() override - { - TestHelper::DestroyEcmaVMWithScope(instance, scope); - } - - PandaVM *instance {nullptr}; - ecmascript::EcmaHandleScope *scope {nullptr}; - JSThread *thread {nullptr}; -}; - -TEST_F(GCTest, CompressGCOne) -{ - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - auto heap = thread->GetEcmaVM()->GetHeap(); - auto compressGc = heap->GetCompressCollector(); - compressGc->RunPhases(); - auto oldSizebase = heap->GetOldSpace()->GetHeapObjectSize(); - size_t oldSizeBefore = 0; - { - [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread); - for (int i = 0; i < 1024; i++) { - factory->NewTaggedArray(512, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE); - } - oldSizeBefore = heap->GetOldSpace()->GetHeapObjectSize(); - EXPECT_TRUE(oldSizeBefore > oldSizebase); - } - compressGc->RunPhases(); - auto oldSizeAfter = heap->GetOldSpace()->GetHeapObjectSize(); - EXPECT_TRUE(oldSizeBefore > oldSizeAfter); -} -} // namespace panda::test diff --git a/tests/runtime/common/huge_object_test.cpp b/tests/runtime/common/huge_object_test.cpp index 64c271d0556dfe50aff30185ab71ee676dc889dc..e414aa8a9fe9e3ec29e5d4109385cc4170e44e11 100644 --- a/tests/runtime/common/huge_object_test.cpp +++ b/tests/runtime/common/huge_object_test.cpp @@ -16,8 +16,6 @@ #include "plugins/ecmascript/runtime/ecma_vm.h" #include "plugins/ecmascript/runtime/global_env.h" #include "plugins/ecmascript/runtime/js_handle.h" -#include "plugins/ecmascript/runtime/mem/space.h" -#include "plugins/ecmascript/runtime/mem/verification.h" #include "plugins/ecmascript/runtime/object_factory.h" #include "plugins/ecmascript/runtime/tagged_array-inl.h" #include "plugins/ecmascript/tests/runtime/common/test_helper.h" @@ -41,7 +39,6 @@ public: { TestHelper::CreateEcmaVMWithScope(instance, thread, scope); thread->GetEcmaVM()->SetEnableForceGC(false); - const_cast(thread->GetEcmaVM()->GetHeap())->SetOnlyMarkSemi(false); } void TearDown() override @@ -86,42 +83,10 @@ TEST_F(HugeObjectTest, LargeArrayKeep) arrayHandle->Set(thread, 0, newObj.GetTaggedValue()); auto ecmaVm = thread->GetEcmaVM(); EXPECT_EQ(*arrayHandle, reinterpret_cast(array)); - ecmaVm->CollectGarbage(TriggerGCType::SEMI_GC); // Trigger GC. - ecmaVm->CollectGarbage(TriggerGCType::HUGE_GC); // Trigger GC. + ecmaVm->CollectGarbage(); // Trigger GC. + ecmaVm->CollectGarbage(); // Trigger GC. EXPECT_EQ(*newObj, array->Get(0).GetTaggedObject()); EXPECT_EQ(*arrayHandle, reinterpret_cast(array)); #endif } - -TEST_F(HugeObjectTest, DISABLED_MultipleArrays) // TODO(vpukhov) -{ -#if !defined(NDEBUG) - auto ecmaVm = thread->GetEcmaVM(); - auto heap = ecmaVm->GetHeap(); - Region *firstPage = nullptr; - Region *secondPage = nullptr; - Region *thirdPage = nullptr; - JSHandle array1(thread, LargeArrayTestCreate(thread)); - firstPage = Region::ObjectAddressToRange(*array1); - { - DISALLOW_GARBAGE_COLLECTION; - [[maybe_unused]] TaggedArray *array2 = LargeArrayTestCreate(thread); - secondPage = Region::ObjectAddressToRange(array2); - } - JSHandle array3(thread, LargeArrayTestCreate(thread)); - thirdPage = Region::ObjectAddressToRange(*array3); - - EXPECT_EQ(firstPage->GetNext(), secondPage); - EXPECT_EQ(secondPage->GetNext(), thirdPage); - - ecmaVm->CollectGarbage(TriggerGCType::HUGE_GC); // Trigger GC. - - EXPECT_EQ(firstPage->GetNext(), thirdPage); - - size_t failCount = 0; - VerifyObjectVisitor objVerifier(heap, &failCount); - heap->GetHugeObjectSpace()->IterateOverObjects(objVerifier); // newspace reference the old space - EXPECT_TRUE(failCount == 0); -#endif -} } // namespace panda::test diff --git a/tests/runtime/common/js_date_test.cpp b/tests/runtime/common/js_date_test.cpp index d2fd80aca096ccdbb6b4a9127383f05cffa0c62b..149fa494015d14890ccf489b07cc2416d48522db 100644 --- a/tests/runtime/common/js_date_test.cpp +++ b/tests/runtime/common/js_date_test.cpp @@ -82,7 +82,7 @@ TEST_F(JSDateTest, MakeTime) TEST_F(JSDateTest, IsoParseStringToMs) { - CString str = "2020-11-19T12:18:18.132Z"; + PandaString str = "2020-11-19T12:18:18.132Z"; JSTaggedValue ms = ecmascript::JSDate::IsoParseStringToMs(str); EXPECT_EQ(ms.GetDouble(), 1605788298132.0); @@ -125,7 +125,7 @@ TEST_F(JSDateTest, IsoParseStringToMs) TEST_F(JSDateTest, LocalParseStringToMs) { - CString str = "Thu Nov 19 2020 20:18:18 GMT+0800"; + PandaString str = "Thu Nov 19 2020 20:18:18 GMT+0800"; JSTaggedValue ms = ecmascript::JSDate::LocalParseStringToMs(str); EXPECT_EQ(ms.GetDouble(), 1605788298000.0); @@ -144,7 +144,7 @@ TEST_F(JSDateTest, LocalParseStringToMs) TEST_F(JSDateTest, UtcParseStringToMs) { - CString str = "Thu, 19 Nov 2020 20:18:18 GMT+0800"; + PandaString str = "Thu, 19 Nov 2020 20:18:18 GMT+0800"; JSTaggedValue ms = ecmascript::JSDate::UtcParseStringToMs(str); EXPECT_EQ(ms.GetDouble(), 1605788298000.0); diff --git a/tests/runtime/common/js_handle_test.cpp b/tests/runtime/common/js_handle_test.cpp index 280a88e590b17dcfbecd9616b32edae04f8125be..ac7530288ddddf3002a9ac5eb7a1264743d905da 100644 --- a/tests/runtime/common/js_handle_test.cpp +++ b/tests/runtime/common/js_handle_test.cpp @@ -62,7 +62,7 @@ TEST_F(JSHandleTest, NewGlobalHandle) globalString = global->NewGlobalHandle(string1.GetTaggedType()); } // trigger GC - thread->GetEcmaVM()->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); + thread->GetEcmaVM()->CollectGarbage(); // check result EXPECT_TRUE(factory->NewFromString("test1")->Compare(*reinterpret_cast(globalString)) == 0); @@ -89,7 +89,7 @@ TEST_F(JSHandleTest, NewGlobalHandle1) uintptr_t globalString[600] = {0}; FillGlobalString(globalString, 600, global, factory, thread); // trigger GC - thread->GetEcmaVM()->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); + thread->GetEcmaVM()->CollectGarbage(); for (int i = 300; i > 200; i--) { global->DisposeGlobalHandle(globalString[i]); } @@ -100,7 +100,7 @@ TEST_F(JSHandleTest, NewGlobalHandle1) 0); } // trigger GC - thread->GetEcmaVM()->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); + thread->GetEcmaVM()->CollectGarbage(); for (int i = 301; i < 600; i++) { std::string test = "test" + std::to_string(i); EXPECT_TRUE(factory->NewFromString(test.c_str())->Compare(*reinterpret_cast(globalString[i])) == @@ -138,7 +138,7 @@ TEST_F(JSHandleTest, DisposeAndNewGlobalHandle) global->DisposeGlobalHandle(globalString[i]); } // trigger GC - thread->GetEcmaVM()->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); + thread->GetEcmaVM()->CollectGarbage(); { [[maybe_unused]] EcmaHandleScope scope_nested(thread); for (int i = 200; i < 400; i++) { @@ -168,14 +168,14 @@ TEST_F(JSHandleTest, DISABLED_NewWeakGlobalHandle) globalString = global->SetWeak(globalString); // trigger GC - thread->GetEcmaVM()->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); + thread->GetEcmaVM()->CollectGarbage(); // check result EXPECT_TRUE(factory->NewFromString("test1")->Compare(*reinterpret_cast(globalString)) == 0); EXPECT_TRUE(global->IsWeak(globalString)); } // trigger GC - thread->GetEcmaVM()->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); + thread->GetEcmaVM()->CollectGarbage(); // check weak reference JSTaggedType result = *reinterpret_cast(globalString); @@ -201,7 +201,7 @@ TEST_F(JSHandleTest, DISABLED_NewWeakGlobalHandle1) global->DisposeGlobalHandle(globalString[i]); } // trigger GC - thread->GetEcmaVM()->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); + thread->GetEcmaVM()->CollectGarbage(); // check result for (int i = 0; i <= 200; i++) { std::string test = "test" + std::to_string(i); @@ -210,7 +210,7 @@ TEST_F(JSHandleTest, DISABLED_NewWeakGlobalHandle1) } } // trigger GC - thread->GetEcmaVM()->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); + thread->GetEcmaVM()->CollectGarbage(); for (int i = 601; i < 800; i++) { EXPECT_TRUE(*reinterpret_cast(globalString[i]) == JSTaggedValue::Undefined().GetRawData()); } diff --git a/tests/runtime/common/js_object_test.cpp b/tests/runtime/common/js_object_test.cpp index ef339335762474c160e5b9b544934b97ca8d3cc5..6b9d17a2b75d2637af6fa63970fcca67a0a60992 100644 --- a/tests/runtime/common/js_object_test.cpp +++ b/tests/runtime/common/js_object_test.cpp @@ -1,5 +1,5 @@ #include "gtest/gtest.h" -#include "mem/c_string.h" +#include "mem/ecma_string.h" #include "test_helper.h" #include "plugins/ecmascript/runtime/ecma_string.h" @@ -450,7 +450,7 @@ TEST_F(JSObjectTest, EnumerableOwnNames) thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(obj_func), obj_func); EXPECT_TRUE(*obj != nullptr); - CString tag_c_str = "x"; + PandaString tag_c_str = "x"; JSHandle tag_string = thread->GetEcmaVM()->GetFactory()->NewFromString(&tag_c_str[0]); JSHandle key(tag_string); @@ -490,7 +490,7 @@ TEST_F(JSObjectTest, SetIntegrityLevelSealed) JSHandle obj1 = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(dynclass1), dynclass1); EXPECT_TRUE(*obj1 != nullptr); - CString undefined_c_str = "x"; + PandaString undefined_c_str = "x"; JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromString(&undefined_c_str[0])); JSHandle value1(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, JSHandle(obj1), key1, value1); @@ -516,7 +516,7 @@ TEST_F(JSObjectTest, SetIntegrityLevelFrozen) thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(dynclass1), dynclass1); EXPECT_TRUE(*obj1 != nullptr); - CString undefined_c_str = "x"; + PandaString undefined_c_str = "x"; JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromString(&undefined_c_str[0])); JSHandle value1(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, JSHandle(obj1), key1, value1); @@ -539,7 +539,7 @@ TEST_F(JSObjectTest, TestIntegrityLevelSealed) JSHandle dynclass1(thread, JSObjectTestCreate(thread)); JSHandle obj1 = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(dynclass1), dynclass1); - CString undefined_c_str = "level"; + PandaString undefined_c_str = "level"; JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromString(&undefined_c_str[0])); JSHandle value1(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, JSHandle(obj1), key1, value1); @@ -563,7 +563,7 @@ TEST_F(JSObjectTest, TestIntegrityLevelFrozen) JSHandle dynclass1(thread, JSObjectTestCreate(thread)); JSHandle obj1 = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(dynclass1), dynclass1); - CString undefined_c_str = "level"; + PandaString undefined_c_str = "level"; JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromString(&undefined_c_str[0])); JSHandle value1(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, JSHandle(obj1), key1, value1); @@ -588,7 +588,7 @@ TEST_F(JSObjectTest, TestIntegrityLevelWithoutProperty) JSHandle obj1( thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(dynclass1), dynclass1)); JSHandle::Cast(obj1)->GetJSHClass()->SetExtensible(false); - CString undefined_c_str = "level"; + PandaString undefined_c_str = "level"; JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromString(&undefined_c_str[0])); // test SetIntegrityLevel::FROZEN diff --git a/tests/runtime/common/js_tagged_queue_test.cpp b/tests/runtime/common/js_tagged_queue_test.cpp index b50a1c8eaaa7fa36af84a7f55f2b2ab902be8805..757cfea88e2014f31a39c2985b24a330ae28830d 100644 --- a/tests/runtime/common/js_tagged_queue_test.cpp +++ b/tests/runtime/common/js_tagged_queue_test.cpp @@ -23,7 +23,6 @@ #include "plugins/ecmascript/runtime/js_handle.h" #include "plugins/ecmascript/runtime/object_factory.h" #include "plugins/ecmascript/runtime/global_env.h" -#include "plugins/ecmascript/runtime/snapshot/mem/snapshot.h" using namespace panda::ecmascript; using namespace panda::coretypes; diff --git a/tests/runtime/common/js_typed_array_test.cpp b/tests/runtime/common/js_typed_array_test.cpp index bf7ab7529d2e85e1f1ab1841000aafd4d685c108..61979fbce1c05505fda0a1d871cddb23fe8882af 100644 --- a/tests/runtime/common/js_typed_array_test.cpp +++ b/tests/runtime/common/js_typed_array_test.cpp @@ -17,6 +17,7 @@ #include "plugins/ecmascript/tests/runtime/common/test_helper.h" using namespace panda::ecmascript; +using namespace std; namespace panda::test { class JSTypedArrayTest : public testing::Test { @@ -44,12 +45,12 @@ public: EcmaHandleScope *scope {nullptr}; JSThread *thread {nullptr}; - const CVector cVecJSType {JSType::JS_INT8_ARRAY, JSType::JS_UINT8_ARRAY, JSType::JS_UINT8_CLAMPED_ARRAY, - JSType::JS_INT16_ARRAY, JSType::JS_UINT16_ARRAY, JSType::JS_INT32_ARRAY, - JSType::JS_UINT32_ARRAY, JSType::JS_FLOAT32_ARRAY, JSType::JS_FLOAT64_ARRAY}; + const vector cVecJSType {JSType::JS_INT8_ARRAY, JSType::JS_UINT8_ARRAY, JSType::JS_UINT8_CLAMPED_ARRAY, + JSType::JS_INT16_ARRAY, JSType::JS_UINT16_ARRAY, JSType::JS_INT32_ARRAY, + JSType::JS_UINT32_ARRAY, JSType::JS_FLOAT32_ARRAY, JSType::JS_FLOAT64_ARRAY}; - // CVector pushed with JSTaggedValue made from compatible input value for the JSType - const CVector cVecHandleTagValValueForTypedArray { + // PandaVector pushed with JSTaggedValue made from compatible input value for the JSType + const vector cVecHandleTagValValueForTypedArray { // Use "(S)(...)" cast to make v in "JSTaggedValue(T v) : coretypes::TaggedValue(v) {}" compatible with S JSTaggedValue((int8_t)(-111)), JSTaggedValue((uint8_t)(222)), JSTaggedValue((uint8_t)(222)), JSTaggedValue((int16_t)(-31111)), JSTaggedValue((uint16_t)(61111)), @@ -260,7 +261,7 @@ TEST_F(JSTypedArrayTest, SetViewedArrayBuffer) */ TEST_F(JSTypedArrayTest, SetTypedArrayName) { - CString cStrName = "cStrName"; + PandaString cStrName = "cStrName"; ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle handleEcmaStrNameFrom = factory->NewFromString(cStrName); JSHandle handleTagValEcmaStrNameFrom = JSHandle::Cast(handleEcmaStrNameFrom); @@ -363,7 +364,7 @@ TEST_F(JSTypedArrayTest, DISABLED_IntegerIndexedElementSet_Int8Array_001) handleInt8Array->SetViewedArrayBuffer(thread, handleTagValArrayBufferFrom); handleInt8Array->SetArrayLength(thread, JSTaggedValue(numElementsInt8Array)); - CVector cVecOpResult = {}; + PandaVector cVecOpResult = {}; for (size_t i = 0; i < numElementsInt8Array; i++) { EXPECT_TRUE(JSTypedArray::IntegerIndexedElementSet( thread, handleTagValInt8Array, JSTaggedValue(i), @@ -460,7 +461,7 @@ TEST_F(JSTypedArrayTest, IntegerIndexedElementSet_Uint8Array_001) handleUint8Array->SetViewedArrayBuffer(thread, handleTagValArrayBufferFrom); handleUint8Array->SetArrayLength(thread, JSTaggedValue(numElementsUint8Array)); - CVector cVecOpResult = {}; + PandaVector cVecOpResult = {}; for (uint32_t i = 0; i < numElementsUint8Array; i++) { EXPECT_TRUE(JSTypedArray::IntegerIndexedElementSet( thread, handleTagValUint8Array, JSTaggedValue(i), @@ -561,7 +562,7 @@ TEST_F(JSTypedArrayTest, IntegerIndexedElementSet_Uint8ClampedArray_001) handleUint8ClampedArray->SetViewedArrayBuffer(thread, handleTagValArrayBufferFrom); handleUint8ClampedArray->SetArrayLength(thread, JSTaggedValue(numElementsUint8ClampedArray)); - CVector cVecOpResult = {}; + PandaVector cVecOpResult = {}; for (uint32_t i = 0; i < numElementsUint8ClampedArray; i++) { EXPECT_TRUE(JSTypedArray::IntegerIndexedElementSet( thread, handleTagValUint8ClampedArray, JSTaggedValue(i), @@ -663,7 +664,7 @@ TEST_F(JSTypedArrayTest, DISABLED_IntegerIndexedElementSet_Int16Array_001) handleInt16Array->SetViewedArrayBuffer(thread, handleTagValArrayBufferFrom); handleInt16Array->SetArrayLength(thread, JSTaggedValue(numElementsInt16Array)); - CVector cVecOpResult = {}; + PandaVector cVecOpResult = {}; for (size_t i = 0; i < numElementsInt16Array; i++) { EXPECT_TRUE(JSTypedArray::IntegerIndexedElementSet( thread, handleTagValInt16Array, JSTaggedValue(i), @@ -767,7 +768,7 @@ TEST_F(JSTypedArrayTest, IntegerIndexedElementSet_Uint16Array_001) handleUint16Array->SetViewedArrayBuffer(thread, handleTagValArrayBufferFrom); handleUint16Array->SetArrayLength(thread, JSTaggedValue(numElementsUint16Array)); - CVector cVecOpResult = {}; + PandaVector cVecOpResult = {}; for (uint32_t i = 0; i < numElementsUint16Array; i++) { EXPECT_TRUE(JSTypedArray::IntegerIndexedElementSet( thread, handleTagValUint16Array, JSTaggedValue(i), @@ -871,7 +872,7 @@ TEST_F(JSTypedArrayTest, DISABLED_IntegerIndexedElementSet_Int32Array_001) handleInt32Array->SetViewedArrayBuffer(thread, handleTagValArrayBufferFrom); handleInt32Array->SetArrayLength(thread, JSTaggedValue(numElementsInt32Array)); - CVector cVecOpResult = {}; + PandaVector cVecOpResult = {}; for (size_t i = 0; i < numElementsInt32Array; i++) { EXPECT_TRUE(JSTypedArray::IntegerIndexedElementSet( thread, handleTagValInt32Array, JSTaggedValue(i), @@ -975,7 +976,7 @@ TEST_F(JSTypedArrayTest, IntegerIndexedElementSet_Uint32Array_001) handleUint32Array->SetViewedArrayBuffer(thread, handleTagValArrayBufferFrom); handleUint32Array->SetArrayLength(thread, JSTaggedValue(numElementsUint32Array)); - CVector cVecOpResult = {}; + PandaVector cVecOpResult = {}; for (uint32_t i = 0; i < numElementsUint32Array; i++) { EXPECT_TRUE(JSTypedArray::IntegerIndexedElementSet( thread, handleTagValUint32Array, JSTaggedValue(i), @@ -1078,7 +1079,7 @@ TEST_F(JSTypedArrayTest, IntegerIndexedElementSet_Float32Array) handleFloat32Array->SetViewedArrayBuffer(thread, handleTagValArrayBufferFrom); handleFloat32Array->SetArrayLength(thread, JSTaggedValue(numElementsFloat32Array)); - CVector cVecOpResult = {}; + PandaVector cVecOpResult = {}; float floatMaxValue = std::numeric_limits::max(); for (uint32_t i = 0; i < numElementsFloat32Array; i++) { EXPECT_TRUE(JSTypedArray::IntegerIndexedElementSet( @@ -1130,7 +1131,7 @@ TEST_F(JSTypedArrayTest, IntegerIndexedElementSet_Float64Array) handleFloat64Array->SetViewedArrayBuffer(thread, handleTagValArrayBufferFrom); handleFloat64Array->SetArrayLength(thread, JSTaggedValue(numElementsFloat64Array)); - CVector cVecOpResult = {}; + PandaVector cVecOpResult = {}; double doubleMaxValue = std::numeric_limits::max(); for (uint32_t i = 0; i < numElementsFloat64Array; i++) { EXPECT_TRUE(JSTypedArray::IntegerIndexedElementSet( diff --git a/tests/runtime/common/js_verification_test.cpp b/tests/runtime/common/js_verification_test.cpp deleted file mode 100644 index 84b1f70637033e8a7b03c34f58475c58c89c535a..0000000000000000000000000000000000000000 --- a/tests/runtime/common/js_verification_test.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "gtest/gtest.h" -#include "test_helper.h" - -#include "plugins/ecmascript/runtime/ecma_string.h" -#include "plugins/ecmascript/runtime/js_thread.h" -#include "include/runtime.h" -#include "plugins/ecmascript/runtime/object_factory.h" -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/tagged_array-inl.h" -#include "plugins/ecmascript/runtime/mem/verification.h" -#include "plugins/ecmascript/runtime/js_object.h" -#include "plugins/ecmascript/runtime/js_hclass.h" -#include "plugins/ecmascript/runtime/mem/space.h" -#include "plugins/ecmascript/runtime/mem/heap.h" - -using namespace panda::ecmascript; -using namespace panda::ecmascript::base; -using namespace panda::coretypes; - -namespace panda::test { -class JSVerificationTest : public testing::Test { -public: - void SetUp() override - { - TestHelper::CreateEcmaVMWithScope(instance, thread, scope); - } - - void TearDown() override - { - TestHelper::DestroyEcmaVMWithScope(instance, scope); - } - - PandaVM *instance {nullptr}; - EcmaHandleScope *scope {nullptr}; - JSThread *thread; -}; - -TEST_F(JSVerificationTest, DISABLED_IsHeapAddress) // issue #5368 -{ - auto ecmaVm = thread->GetEcmaVM(); - auto heap = ecmaVm->GetHeap(); - auto objectFactory = ecmaVm->GetFactory(); - auto verifier = Verification(heap); - EXPECT_FALSE(verifier.IsHeapAddress(reinterpret_cast(1))); - EXPECT_FALSE(verifier.IsHeapAddress(reinterpret_cast(2))); - EXPECT_FALSE(verifier.IsHeapAddress(nullptr)); - EXPECT_FALSE(verifier.IsHeapAddress(&verifier)); - - auto funcVerify = [&](ObjectHeader *object, Verification &v, const Heap *h) { - EXPECT_TRUE(v.IsHeapAddress(reinterpret_cast(object))); - EXPECT_TRUE(h->ContainObject(TaggedObject::Cast(object))); - EXPECT_TRUE(h->IsLive(TaggedObject::Cast(object))); - }; - - // new space object - JSHandle string = objectFactory->NewFromString("123"); - funcVerify(*string, verifier, heap); - - // old space object - auto oldArray = objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE); - funcVerify(*oldArray, verifier, heap); - - // no movable object - auto nonMovableArray = objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::NON_MOVABLE); - funcVerify(*nonMovableArray, verifier, heap); -} - -TEST_F(JSVerificationTest, DISABLED_VerifyHeapObjects) // issue #5368 -{ - auto ecmaVm = thread->GetEcmaVM(); - auto heap = const_cast(ecmaVm->GetHeap()); - auto objectFactory = ecmaVm->GetFactory(); - EXPECT_TRUE(heap->VerifyHeapObjects() == 0); // failcount is 0 - - JSTaggedValue oldArray; - auto verifier = Verification(heap); - { - EcmaHandleScope handleScope(thread); - auto newArray = objectFactory->NewTaggedArray(1, JSTaggedValue::Undefined(), MemSpaceType::SEMI_SPACE); - - oldArray = - (objectFactory->NewTaggedArray(1, JSTaggedValue::Undefined(), MemSpaceType::NON_MOVABLE)).GetTaggedValue(); - newArray->Set(thread, 0, oldArray); - } - ecmaVm->GetGC()->WaitForGC(GCTask(GCTaskCause::EXPLICIT_CAUSE)); - EXPECT_TRUE(verifier.VerifyRoot() == 0); - size_t failCount = 0; - VerifyObjectVisitor objVerifier(heap, &failCount); - heap->GetNewSpace()->IterateOverObjects(objVerifier); // newspace reference the old space - EXPECT_TRUE(failCount != 0); -} -} // namespace panda::test diff --git a/tests/runtime/common/large_object_test.cpp b/tests/runtime/common/large_object_test.cpp index 6ba931dcc58ffb16b48876486cbae8035ae09b6f..14f7ead981d8f65829d69df4b893537e16e916be 100644 --- a/tests/runtime/common/large_object_test.cpp +++ b/tests/runtime/common/large_object_test.cpp @@ -24,8 +24,6 @@ #include "plugins/ecmascript/runtime/js_handle.h" #include "plugins/ecmascript/runtime/tagged_array-inl.h" #include "plugins/ecmascript/runtime/object_factory.h" -#include "plugins/ecmascript/runtime/mem/space.h" -#include "plugins/ecmascript/runtime/mem/verification.h" using namespace panda::ecmascript; using namespace panda::coretypes; @@ -88,32 +86,4 @@ TEST_F(LargeObjectTest, LargeArrayKeep) #endif } -TEST_F(LargeObjectTest, DISABLED_MultipleArrays) // issue #5368 -{ -#if !defined(NDEBUG) - auto ecmaVm = thread->GetEcmaVM(); - auto heap = ecmaVm->GetHeap(); - const HugeObjectSpace *space = heap->GetHugeObjectSpace(); - JSHandle array1(thread, LargeArrayTestCreate(thread)); - { - DISALLOW_GARBAGE_COLLECTION; - [[maybe_unused]] TaggedArray *array2 = LargeArrayTestCreate(thread); - } - JSHandle array3(thread, LargeArrayTestCreate(thread)); - - Region *firstPage = space->GetRegionList().GetFirst(); - Region *secondPage = firstPage->GetNext(); - Region *thirdPage = secondPage->GetNext(); - - ecmaVm->GetGC()->WaitForGCInManaged(GCTask(GCTaskCause::EXPLICIT_CAUSE)); // Trigger GC. - - EXPECT_EQ(firstPage->GetNext(), thirdPage); - - size_t failCount = 0; - VerifyObjectVisitor objVerifier(heap, &failCount); - heap->GetHugeObjectSpace()->IterateOverObjects(objVerifier); // newspace reference the old space - EXPECT_TRUE(failCount == 0); -#endif -} - } // namespace panda::test diff --git a/tests/runtime/common/mem_controller_test.cpp b/tests/runtime/common/mem_controller_test.cpp deleted file mode 100644 index f4201425eecf065e09a6dc246f73777b4295d156..0000000000000000000000000000000000000000 --- a/tests/runtime/common/mem_controller_test.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "plugins/ecmascript/runtime/ecma_string.h" -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/js_hclass.h" -#include "plugins/ecmascript/runtime/js_object-inl.h" -#include "plugins/ecmascript/runtime/js_thread.h" - -#include "plugins/ecmascript/runtime/mem/heap.h" -#include "plugins/ecmascript/runtime/mem/space.h" -#include "plugins/ecmascript/runtime/object_factory.h" -#include "plugins/ecmascript/runtime/tagged_array-inl.h" -#include "plugins/ecmascript/tests/runtime/common/test_helper.h" - -using namespace panda::ecmascript; -using namespace panda::ecmascript::base; - -namespace panda::test { -class MemControllerTest : public testing::Test { -public: - static void SetUpTestCase() - { - GTEST_LOG_(INFO) << "SetUpTestCase"; - } - - static void TearDownTestCase() - { - GTEST_LOG_(INFO) << "TearDownCase"; - } - - void SetUp() override - { - TestHelper::CreateEcmaVMWithScope(instance, thread, scope); - } - - void TearDown() override - { - TestHelper::DestroyEcmaVMWithScope(instance, scope); - } - - PandaVM *instance {nullptr}; - EcmaHandleScope *scope {nullptr}; - JSThread *thread {nullptr}; -}; - -TEST_F(MemControllerTest, AllocationVerify) -{ -#ifdef NDEBUG - auto ecmaVm = thread->GetEcmaVM(); - auto heap = const_cast(ecmaVm->GetHeap()); - auto objectFactory = ecmaVm->GetFactory(); - auto memController = heap->GetMemController(); - - heap->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); - - for (int i = 0; i < 1024; i++) { - // old space object - [[maybe_unused]] auto oldArray = - objectFactory->NewTaggedArray(128, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE); - } - sleep(5); - heap->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); - double mutatorSpeed1 = memController->GetCurrentOldSpaceAllocationThroughtputPerMS(0); - for (int i = 0; i < 1024; i++) { - // old space object - [[maybe_unused]] auto oldArray = - objectFactory->NewTaggedArray(128, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE); - } - sleep(10); - - heap->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); - double mutatorSpeed2 = memController->GetCurrentOldSpaceAllocationThroughtputPerMS(0); - ASSERT_TRUE(mutatorSpeed2 < mutatorSpeed1); -#endif -} - -TEST_F(MemControllerTest, VerifyMutatorSpeed) -{ -#ifdef NDEBUG - auto ecmaVm = thread->GetEcmaVM(); - auto heap = const_cast(ecmaVm->GetHeap()); - auto objectFactory = ecmaVm->GetFactory(); - auto memController = heap->GetMemController(); - - heap->CollectGarbage(TriggerGCType::SEMI_GC); - size_t oldSpaceAllocatedSizeBefore = memController->GetOldSpaceAllocAccumulatorSize(); - size_t nonMovableSpaceAllocatedSizeBefore = memController->GetNonMovableSpaceAllocAccumulatorSize(); - double allocDurationBefore = memController->GetAllocTimeMs(); - sleep(1); - - // new space object - auto newArray = objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::SEMI_SPACE); - // old space object - auto oldArray = objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE); - // non movable object - auto nonMovableArray = objectFactory->NewTaggedArray(2, JSTaggedValue::Undefined(), MemSpaceType::NON_MOVABLE); - - // huge space object - static constexpr size_t SIZE = 1024 * 1024; - auto hugeArray = objectFactory->NewTaggedArray(SIZE); - - ASSERT_TRUE(heap->GetNewSpace()->GetAllocatedSizeSinceGC() == - newArray->ComputeSize(JSTaggedValue::TaggedTypeSize(), 2)); - - heap->CollectGarbage(TriggerGCType::SEMI_GC); - - size_t oldSpaceAllocatedSizeAfter = memController->GetOldSpaceAllocAccumulatorSize(); - size_t nonMovableSpaceAllocatedSizeAfter = memController->GetNonMovableSpaceAllocAccumulatorSize(); - double allocDurationAfter = memController->GetAllocTimeMs(); - - size_t hugeObjectAllocSizeInLastGC = memController->GetHugeObjectAllocSizeSinceGC(); - - ASSERT_TRUE(allocDurationAfter - allocDurationBefore > 1000); - ASSERT_TRUE(oldSpaceAllocatedSizeAfter - oldSpaceAllocatedSizeBefore == - oldArray->ComputeSize(JSTaggedValue::TaggedTypeSize(), 2)); - ASSERT_TRUE(nonMovableSpaceAllocatedSizeAfter - nonMovableSpaceAllocatedSizeBefore == - nonMovableArray->ComputeSize(JSTaggedValue::TaggedTypeSize(), 2)); - // The allocated size of huge object must be larger than the object size. - ASSERT_TRUE(hugeObjectAllocSizeInLastGC > hugeArray->ComputeSize(JSTaggedValue::TaggedTypeSize(), SIZE)); -#endif -} -} // namespace panda::test diff --git a/tests/runtime/common/object_factory_test.cpp b/tests/runtime/common/object_factory_test.cpp index b23562aee22408f057b9837ed12b51fbf9aa9089..134283c6bb82c53ff29a5ed6b92f246c30cffd95 100644 --- a/tests/runtime/common/object_factory_test.cpp +++ b/tests/runtime/common/object_factory_test.cpp @@ -90,7 +90,7 @@ TEST_F(ObjectFactoryTest, DISABLED_NewJSObjectByConstructor) // TODO(vpukhov) // check gc handle update auto *prototype = cls->GetPrototype().GetTaggedObject(); - thread->GetEcmaVM()->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); + thread->GetEcmaVM()->CollectGarbage(); // CompressGC not the same EXPECT_TRUE(prototype != newObjCls->GetPrototype().GetTaggedObject()); thread->GetEcmaVM()->SetEnableForceGC(true); diff --git a/tests/runtime/common/tagged_value_test.cpp b/tests/runtime/common/tagged_value_test.cpp index cc658406dda73b12ba616014e35cd247e6cd6118..b8f792d13c13ec05b844ef3b409068e8cda2a176 100644 --- a/tests/runtime/common/tagged_value_test.cpp +++ b/tests/runtime/common/tagged_value_test.cpp @@ -27,7 +27,6 @@ #include "include/runtime.h" #include "plugins/ecmascript/runtime/ecma_vm.h" #include "plugins/ecmascript/runtime/global_env.h" -#include "plugins/ecmascript/runtime/snapshot/mem/snapshot.h" using namespace panda::ecmascript; @@ -752,7 +751,7 @@ TEST_F(JSTaggedValueTest, ToPropertyKey) EXPECT_TRUE(key == result); } -void check_ok_string(JSThread *thread, const JSHandle &tagged, CString &right_c_str) +void check_ok_string(JSThread *thread, const JSHandle &tagged, PandaString &right_c_str) { JSHandle result = JSTaggedValue::ToString(thread, tagged); JSHandle right_string = thread->GetEcmaVM()->GetFactory()->NewFromString(right_c_str); @@ -760,7 +759,7 @@ void check_ok_string(JSThread *thread, const JSHandle &tagged, CS EcmaString::Cast(right_string.GetObject()))); } -void CheckOkString(JSThread *thread, const JSHandle &tagged, CString &rightCStr) +void CheckOkString(JSThread *thread, const JSHandle &tagged, PandaString &rightCStr) { JSHandle result = JSTaggedValue::ToString(thread, tagged); JSHandle rightString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(rightCStr); @@ -770,7 +769,7 @@ void CheckOkString(JSThread *thread, const JSHandle &tagged, CStr TEST_F(JSTaggedValueTest, ToString) { - CString rightCStr = ""; + PandaString rightCStr = ""; CheckOkString(thread, JSHandle(thread, JSTaggedValue()), rightCStr); rightCStr = "undefined"; diff --git a/tests/runtime/common/visitor_compatibility_tests.cpp b/tests/runtime/common/visitor_compatibility_tests.cpp deleted file mode 100644 index 714b23d0e687b7ddc2e2f650f41cfaa7da5cce5d..0000000000000000000000000000000000000000 --- a/tests/runtime/common/visitor_compatibility_tests.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include "gtest/gtest.h" - -#include "class_linker/program_object.h" -#include "ecma_module.h" -#include "jobs/micro_job_queue.h" -#include "js_array.h" -#include "js_array_iterator.h" -#include "js_arraybuffer.h" -#include "js_async_function.h" -#include "js_date.h" -#include "js_for_in_iterator.h" -#include "js_hclass.h" -#include "js_locale.h" -#include "js_map.h" -#include "js_map_iterator.h" -#include "js_promise.h" -#include "js_regexp.h" -#include "js_set.h" -#include "js_set_iterator.h" -#include "js_string_iterator.h" -#include "js_tagged_value.h" -#include "mem/heap_roots.h" -#include "object_factory.h" -#include "test_helper.h" -#include "js_int8_array.h" -#include "js_uint8_array.h" -#include "js_uint8_clamped_array.h" -#include "js_int16_array.h" -#include "js_uint16_array.h" -#include "js_int32_array.h" -#include "js_uint32_array.h" -#include "js_float32_array.h" -#include "js_float64_array.h" -#include "js_primitive_ref.h" -#include "js_weak_container.h" -#include "js_dataview.h" -#include "js_typed_array.h" -#include "ic/ic_handler.h" -#include "ic/proto_change_details.h" -#include "js_relative_time_format.h" -#include "js_number_format.h" -#include "js_date_time_format.h" -#include "js_handle.h" -#include "js_object.h" -#include "base/builtins_base.h" -#include "js_arguments.h" -#include "js_generator_object.h" -#include "mem/heap_roots-inl.h" -#include "builtins.h" -#include "ecma_vm.h" -#include "global_env.h" -#include "js_thread.h" - -#include "runtime/include/class.h" -#include "runtime/include/coretypes/array.h" -#include "runtime/include/coretypes/dyn_objects.h" -#include "runtime/include/hclass.h" -#include "runtime/include/object_header.h" -#include "runtime/include/runtime.h" -#include "runtime/include/thread.h" - -using namespace panda::coretypes; -using namespace panda::ecmascript; -using namespace panda::ecmascript::base; - -namespace panda::test { - -template -void VisitAllClassTaggedValues(coretypes::DynClass *dyn_class, const Visitor &v) -{ - HClass *klass = dyn_class->GetHClass(); - - size_t klass_size = dyn_class->ClassAddr()->GetObjectSize(); - - uintptr_t start_addr = reinterpret_cast(klass) + sizeof(HClass); - size_t body_size = klass_size - sizeof(DynClass) - sizeof(HClass); - size_t num_of_fields = body_size / TaggedValue::TaggedTypeSize(); - for (size_t i = 0; i < num_of_fields; i++) { - auto field_addr = start_addr + i * TaggedValue::TaggedTypeSize(); - v(field_addr); - } -} - -template -void VisitAllObjectTaggedValues(ObjectHeader *object, BaseClass *cls, const Visitor &v) -{ - auto obj_body_size = cls->GetObjectSize() - ObjectHeader::ObjectHeaderSize(); - ASSERT(obj_body_size % TaggedValue::TaggedTypeSize() == 0); - int num_of_fields = static_cast(obj_body_size / TaggedValue::TaggedTypeSize()); - size_t start_addr = reinterpret_cast(object) + ObjectHeader::ObjectHeaderSize(); - uintptr_t method_addr = - static_cast(cls)->HasMethod() ? reinterpret_cast(object) + HClass::METHOD_OFFSET : 0; - for (int i = 0; i < num_of_fields; i++) { - auto addr = start_addr + i * TaggedValue::TaggedTypeSize(); - if (addr != method_addr) { - v(addr); - } - } -} - -template -void VisitAllArrayTaggedValues(coretypes::Array *array_object, const Visitor &v) -{ - auto array_length = array_object->GetLength(); - uintptr_t array_start_addr = reinterpret_cast(array_object) + coretypes::Array::GetDataOffset(); - for (coretypes::array_size_t i = 0; i < array_length; i++) { - auto element_addr = array_start_addr + i * TaggedValue::TaggedTypeSize(); - v(element_addr); - } -} - -template -void AllTaggedValueVisitor(ObjectHeader *object, BaseClass *cls, const Visitor &v) -{ - auto hclass = static_cast(cls); - if (hclass->IsHClass()) { - VisitAllClassTaggedValues(static_cast(object), v); - } else if (hclass->IsArray()) { - VisitAllArrayTaggedValues(static_cast(object), v); - } else { - VisitAllObjectTaggedValues(object, cls, v); - } -} - -std::vector SwitchCaseVisitor(ObjectHeader *object, JSHClass *klass) -{ - std::vector res; - EcmaObjectRangeVisitor visitor = [&res](ObjectHeader *, ObjectSlot start, ObjectSlot end) { - for (ObjectSlot slot = start; slot < end; slot++) { - res.push_back(slot.SlotAddress()); - } - }; - - HeapRootManager hrm(static_cast(ManagedThread::GetCurrent()->GetVM())); - hrm.MarkObjectBody(object, klass, visitor); - return res; -} - -std::vector UnifiedVisitor(ObjectHeader *object, JSHClass *klass) -{ - std::vector res; - AllTaggedValueVisitor(object, klass, [&res](uintptr_t val) { res.push_back(val); }); - return res; -} - -class VisitorCompatibilityTest : public testing::Test { -public: - void SetUp() override - { - TestHelper::CreateEcmaVMWithScope(instance, thread, scope); - if (thread == nullptr) { - std::cerr << "Error in initialization" << std::endl; - std::abort(); - } - ecma_vm = thread->GetEcmaVM(); - factory = ecma_vm->GetFactory(); - } - - void TearDown() override - { - TestHelper::DestroyEcmaVMWithScope(instance, scope); - } - - bool Cmp(std::vector &&vec1, std::vector &&vec2) - { - if (vec1.size() != vec2.size()) { - return false; - } - while (!vec1.empty()) { - auto it = std::find(vec2.rbegin(), vec2.rend(), vec1.back()); - if (it == vec2.rend()) { - return false; - } - vec2.erase(std::next(it).base()); - vec1.pop_back(); - } - return true; - } - - bool WrappedCmp(ObjectHeader *object, JSHClass *klass) - { - return Cmp(SwitchCaseVisitor(object, klass), UnifiedVisitor(object, klass)); - } - - PandaVM *instance {nullptr}; - EcmaVM *ecma_vm {nullptr}; - EcmaHandleScope *scope {nullptr}; - ObjectFactory *factory {nullptr}; - JSThread *thread; -}; - -TEST_F(VisitorCompatibilityTest, JSObject) -{ - JSHandle env = ecma_vm->GetGlobalEnv(); - - JSHandle object_function(env->GetObjectFunction()); - JSHandle obj = - factory->NewJSObjectByConstructor(object_function, JSHandle(object_function)); - auto klass = obj->GetJSHClass(); - ASSERT_EQ(klass->GetObjectType(), JSType::JS_OBJECT); - ASSERT_TRUE(WrappedCmp(*obj, klass)); -} - -TEST_F(VisitorCompatibilityTest, GlobalEnv) -{ - JSHandle env = ecma_vm->GetGlobalEnv(); - auto klass = JSHClass::Cast(env->ClassAddr()); - ASSERT_EQ(klass->GetObjectType(), JSType::GLOBAL_ENV); - ASSERT_TRUE(WrappedCmp(*env, klass)); -} - -TEST_F(VisitorCompatibilityTest, JSGlobalObject) -{ - JSHandle env = ecma_vm->GetGlobalEnv(); - - auto global_object = env->GetJSGlobalObject(); - auto klass = JSObject::Cast(global_object.GetTaggedValue())->GetJSHClass(); - ASSERT_EQ(klass->GetObjectType(), JSType::JS_GLOBAL_OBJECT); - ASSERT_TRUE(WrappedCmp(JSObject::Cast(global_object.GetTaggedValue()), klass)); -} - -TEST_F(VisitorCompatibilityTest, JSTaggedArray) -{ - auto array = factory->NewTaggedArray(4); - auto klass = array->ClassAddr(); - ASSERT_EQ(klass->GetObjectType(), JSType::TAGGED_ARRAY); - ASSERT_TRUE(WrappedCmp(*array, klass)); -} - -TEST_F(VisitorCompatibilityTest, HClass) -{ - JSHandle env = ecma_vm->GetGlobalEnv(); - JSHClass *kls = env->ClassAddr(); - auto klass_klass = kls->GetManagedObject()->ClassAddr(); - - ASSERT_EQ(klass_klass->GetObjectType(), JSType::HCLASS); - ASSERT_TRUE(WrappedCmp(kls->GetManagedObject(), klass_klass)); -} - -TEST_F(VisitorCompatibilityTest, Program) -{ - auto hclass = DynClass::Cast(thread->GlobalConstants()->GetProgramClass().GetHeapObject())->GetHClass(); - auto program = factory->NewProgram(); - auto klass = JSHClass::Cast(hclass); - ASSERT_TRUE(WrappedCmp(*program, klass)); -} - -TEST_F(VisitorCompatibilityTest, JSProxy) -{ - auto hclass = DynClass::Cast(thread->GlobalConstants()->GetJSProxyOrdinaryClass().GetHeapObject())->GetHClass(); - JSTaggedValue object(hclass->GetManagedObject()); - JSHandle target(thread, object); - JSHandle handler(thread, object); - JSHandle proxy = factory->NewJSProxy(target, handler); - auto klass = JSHClass::Cast(hclass); - ASSERT_EQ(klass->GetObjectType(), JSType::JS_PROXY); - ASSERT_TRUE(WrappedCmp(*proxy, klass)); -} - -TEST_F(VisitorCompatibilityTest, JSFunction) -{ - JSHandle env = ecma_vm->GetGlobalEnv(); - JSHandle functionClass = JSHandle::Cast(env->GetFunctionClassWithoutName()); - JSHandle jsFunc = - factory->NewJSFunctionByDynClass(env, nullptr, functionClass, FunctionKind::CLASS_CONSTRUCTOR); - auto klass = JSHClass::Cast(functionClass->GetHClass()); - ASSERT_EQ(klass->GetObjectType(), JSType::JS_FUNCTION); - ASSERT_TRUE(WrappedCmp(*jsFunc, klass)); -} - -// TODO(maksenov): add tests for all remaining object types - -} // namespace panda::test diff --git a/tests/runtime/hprof/heap_tracker_test.cpp b/tests/runtime/hprof/heap_tracker_test.cpp deleted file mode 100644 index 14badabe55a786767407fc1893620b2ea49cc21e..0000000000000000000000000000000000000000 --- a/tests/runtime/hprof/heap_tracker_test.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include "plugins/ecmascript/runtime/ecma_string.h" -#include "plugins/ecmascript/runtime/global_env.h" -#include "plugins/ecmascript/runtime/hprof/heap_profiler_interface.h" -#include "plugins/ecmascript/runtime/hprof/heap_snapshot_json_serializer.h" - -#include "plugins/ecmascript/runtime/js_tagged_value.h" -#include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/tests/runtime/common/test_helper.h" - -using namespace panda::ecmascript; - -namespace panda::test { -class HeapTrackerTest : public testing::Test { -public: - static void SetUpTestCase() - { - GTEST_LOG_(INFO) << "SetUpTestCase"; - } - - static void TearDownTestCase() - { - GTEST_LOG_(INFO) << "TearDownCase"; - } - - void SetUp() override - { - TestHelper::CreateEcmaVMWithScope(instance, thread, scope); - EcmaVM::Cast(instance)->SetEnableForceGC(false); - } - - void TearDown() override - { - TestHelper::DestroyEcmaVMWithScope(instance, scope); - } - - PandaVM *instance {nullptr}; - EcmaHandleScope *scope {nullptr}; - JSThread *thread {nullptr}; -}; - -TEST_F(HeapTrackerTest, DISABLED_HeapTracker) // issue #5368 -{ - [[maybe_unused]] EcmaHandleScope handleScope(thread); - HeapProfilerInterface *heapProfile = HeapProfilerInterface::CreateHeapProfiler(thread); - heapProfile->StartHeapTracking(thread, 50); - sleep(1); - int count = 100; - while (count-- > 0) { - thread->GetEcmaVM()->GetFactory()->NewJSAsyncFuncObject(); - } - sleep(1); - count = 100; - while (count-- > 0) { - thread->GetEcmaVM()->GetFactory()->NewJSSymbol(); - } - sleep(1); - count = 100; - while (count-- > 0) { - JSHandle string = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("Hello World"); - thread->GetEcmaVM()->GetFactory()->NewJSString(JSHandle(string)); - } - - // Create file test.heaptimeline - std::string fileName = "test.heaptimeline"; - fstream outputString(fileName, std::ios::out); - outputString.close(); - outputString.clear(); - - heapProfile->StopHeapTracking(thread, DumpFormat::JSON, fileName.c_str()); - HeapProfilerInterface::Destroy(thread, heapProfile); - - // Check - fstream inputStream(fileName, std::ios::in); - std::string line; - std::string emptySample = "\"samples\":"; - std::string firstSample = "\"samples\":[0, "; - int emptySize = emptySample.size(); - bool isFind = false; - while (getline(inputStream, line)) { - if (line.substr(0, emptySize) == emptySample) { - ASSERT_TRUE(line.substr(0, firstSample.size()) == firstSample); - isFind = true; - } - } - ASSERT_TRUE(isFind); - - inputStream.close(); - inputStream.clear(); - std::remove(fileName.c_str()); -} -} // namespace panda::test diff --git a/tests/runtime/hprof/hprof_test.cpp b/tests/runtime/hprof/hprof_test.cpp deleted file mode 100644 index 8c9048bd6ee82068885c98d6734eb06b9eb5b110..0000000000000000000000000000000000000000 --- a/tests/runtime/hprof/hprof_test.cpp +++ /dev/null @@ -1,341 +0,0 @@ -/** - * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. - */ - -#include "gtest/gtest.h" -#include "test_helper.h" - -#include "plugins/ecmascript/runtime/object_factory.h" -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/global_env.h" -#include "include/runtime.h" -#include "plugins/ecmascript/runtime/js_thread.h" -#include "plugins/ecmascript/runtime/hprof/heap_profiler.h" -#include "plugins/ecmascript/runtime/hprof/heap_profiler_interface.h" -#include "plugins/ecmascript/runtime/hprof/heap_snapshot.h" -#include "plugins/ecmascript/runtime/hprof/heap_snapshot_json_serializer.h" -#include "plugins/ecmascript/runtime/hprof/string_hashmap.h" - -#include -#include - -using namespace panda::coretypes; -using namespace panda::ecmascript; - -namespace panda::test { -// All HProf tests was disabled, see issue #5368 -class HProfTest : public testing::Test { -public: - void SetUp() override - { - TestHelper::CreateEcmaVMWithScope(instance, thread, scope); - } - - void TearDown() override - { - TestHelper::DestroyEcmaVMWithScope(instance, scope); - } - -protected: - PandaVM *instance; - JSThread *thread; - EcmaHandleScope *scope {nullptr}; -}; - -class HProfTestHelper { -public: - explicit HProfTestHelper(const CString &aFilePath) : filePath(aFilePath) {} - ~HProfTestHelper() = default; - - bool IsFileExist() - { - bool exist = false; - exist = SafeOpenFile(); - SafeCloseFile(); - return exist; - } - - bool RemoveExistingFile() - { - int code = 0; - if (IsFileExist()) { - code = std::remove(filePath.c_str()); - } - return code == 0 ? true : false; - } - - bool GenerateHeapDump(JSThread *thread) - { - int retry = 2; - RemoveExistingFile(); - HeapProfilerInterface::DumpHeapSnapShot(thread, DumpFormat::JSON, filePath.c_str()); - while (!IsFileExist() && retry > 0) { - retry--; - HeapProfilerInterface::DumpHeapSnapShot(thread, DumpFormat::JSON, filePath.c_str()); - } - return IsFileExist(); - } - - bool ContrastJSONLineHeader(int lineId, CString lineHeader) - { - bool all_same = false; - if (!SafeOpenFile()) { // No JSON File - all_same = false; - SafeCloseFile(); - } else { - CString line; - int i = 1; - while (getline(inputFile, line)) { - if (i == lineId && line.find(lineHeader) != line.npos) { - all_same = true; - break; - } - i++; - } - SafeCloseFile(); - } - - return all_same; - } - - bool ContrastJSONSectionPayload(CString dataLable, int fieldNum) - { - if (!SafeOpenFile()) { // No JSON File - SafeCloseFile(); - return false; - } - CString line; - int i = 1; - while (getline(inputFile, line)) { - if (i > 10 && line.find(dataLable) != line.npos) { // Hit the line - CString::size_type pos = 0; - int loop = 0; - while ((pos = line.find(",", pos)) != line.npos) { - pos++; - loop++; // "," count - } - SafeCloseFile(); - return loop == fieldNum - 1; - break; - } - i++; // Search Next Line - } - SafeCloseFile(); - return false; // Lost the Line - } - - bool ContrastJSONClousure() - { - if (!SafeOpenFile()) { // No JSON File - SafeCloseFile(); - return false; - } - CString line_bk; // The Last Line - CString line; - while (getline(inputFile, line)) { - line_bk = line; - } - SafeCloseFile(); - return line_bk.compare("}") == 0; - } - - int ExtractCountFromMeta(CString typeLable) - { - if (!SafeOpenFile()) { // No JSON File - SafeCloseFile(); - return -1; - } - CString line; - int i = 1; - while (getline(inputFile, line)) { - int length = line.length() - typeLable.length() - 1; - if (line.find(typeLable) != line.npos) { // Get - if (line.find(",") == line.npos) { // "trace_function_count" end without "," - length = line.length() - typeLable.length(); - } - line = line.substr(typeLable.length(), length); - SafeCloseFile(); - return std::stoi(line.c_str()); - } - i++; - } - SafeCloseFile(); - return -1; - } - - int ExtractCountFromPayload(CString dataLabel) - { - if (!SafeOpenFile()) { // No JSON File - SafeCloseFile(); - return -1; - } - CString line; - bool hit = false; - int loop = 0; - while (getline(inputFile, line)) { - if (!hit && line.find(dataLabel) != line.npos) { // Get - loop += 1; // First Line - hit = true; - if (line.find("[]") != line.npos) { // Empty - loop = 0; - SafeCloseFile(); - return loop; - } - continue; - } - if (hit) { - if (line.find("],") != line.npos) { // Reach End - loop += 1; // End Line - SafeCloseFile(); - return loop; - } - loop++; - continue; - } - } - SafeCloseFile(); - - return -1; - } - -private: - bool SafeOpenFile() - { - inputFile.clear(); - inputFile.open(filePath.c_str(), std::ios::in); - int retry = 2; - while (!inputFile.good() && retry > 0) { - inputFile.open(filePath.c_str(), std::ios::in); - retry--; - } - return inputFile.good(); - } - - void SafeCloseFile() - { - inputFile.close(); - inputFile.clear(); // Reset File status - } - CString filePath; - std::fstream inputFile; -}; - -TEST_F(HProfTest, DISABLED_GenerateFileForManualCheck) -{ - HProfTestHelper tester("hprof_json_test.heapsnapshot"); - ASSERT_TRUE(tester.GenerateHeapDump(thread)); -} - -TEST_F(HProfTest, DISABLED_GenerateFile) -{ - HProfTestHelper tester("GenerateFile.heapsnapshot"); - ASSERT_TRUE(tester.GenerateHeapDump(thread)); - ASSERT_TRUE(tester.RemoveExistingFile()); -} - -TEST_F(HProfTest, DISABLED_ParseJSONHeader) -{ - HProfTestHelper tester("ParseJSONHeader.heapsnapshot"); - ASSERT_TRUE(tester.GenerateHeapDump(thread)); - ASSERT_TRUE(tester.ContrastJSONLineHeader(1, "{\"snapshot\":")); - ASSERT_TRUE(tester.ContrastJSONLineHeader(2, "{\"meta\":")); - ASSERT_TRUE(tester.ContrastJSONLineHeader(3, "{\"node_fields\":")); - ASSERT_TRUE(tester.ContrastJSONLineHeader(4, "\"node_types\":")); - ASSERT_TRUE(tester.ContrastJSONLineHeader(5, "\"edge_fields\":")); - ASSERT_TRUE(tester.ContrastJSONLineHeader(6, "\"edge_types\":")); - ASSERT_TRUE(tester.ContrastJSONLineHeader(7, "\"trace_function_info_fields\":")); - ASSERT_TRUE(tester.ContrastJSONLineHeader(8, "\"trace_node_fields\":")); - ASSERT_TRUE(tester.ContrastJSONLineHeader(9, "\"sample_fields\":")); - ASSERT_TRUE(tester.ContrastJSONLineHeader(10, "\"location_fields\":")); - ASSERT_TRUE(tester.RemoveExistingFile()); -} - -TEST_F(HProfTest, DISABLED_ContrastNode) -{ - HProfTestHelper tester("ContrastNode.heapsnapshot"); - ASSERT_TRUE(tester.GenerateHeapDump(thread)); - ASSERT_TRUE(tester.ContrastJSONSectionPayload("\"nodes\":", 7)); - ASSERT_TRUE(tester.RemoveExistingFile()); -} - -TEST_F(HProfTest, DISABLED_ContrastEdge) -{ - HProfTestHelper tester("ContrastEdge.heapsnapshot"); - ASSERT_TRUE(tester.GenerateHeapDump(thread)); - ASSERT_TRUE(tester.ContrastJSONSectionPayload("\"edges\":", 3)); - ASSERT_TRUE(tester.RemoveExistingFile()); -} - -TEST_F(HProfTest, DISABLED_ContrastTraceFunctionInfo) -{ - HProfTestHelper tester("ContrastTraceFunctionInfo.heapsnapshot"); - ASSERT_TRUE(tester.GenerateHeapDump(thread)); - ASSERT_TRUE(tester.ContrastJSONSectionPayload("\"trace_function_infos\":", 2)); // Empty - ASSERT_TRUE(tester.RemoveExistingFile()); -} - -TEST_F(HProfTest, DISABLED_ContrastTraceTree) -{ - HProfTestHelper tester("ContrastTraceTree.heapsnapshot"); - ASSERT_TRUE(tester.GenerateHeapDump(thread)); - ASSERT_TRUE(tester.ContrastJSONSectionPayload("\"trace_tree\":", 2)); // Empty - ASSERT_TRUE(tester.RemoveExistingFile()); -} - -TEST_F(HProfTest, DISABLED_ContrastSamples) -{ - HProfTestHelper tester("ContrastSamples.heapsnapshot"); - ASSERT_TRUE(tester.GenerateHeapDump(thread)); - ASSERT_TRUE(tester.ContrastJSONSectionPayload("\"samples\":", 2)); // Empty - ASSERT_TRUE(tester.RemoveExistingFile()); -} - -TEST_F(HProfTest, DISABLED_ContrastLocations) -{ - HProfTestHelper tester("ContrastLocations.heapsnapshot"); - ASSERT_TRUE(tester.GenerateHeapDump(thread)); - ASSERT_TRUE(tester.ContrastJSONSectionPayload("\"locations\":", 2)); // Empty - ASSERT_TRUE(tester.RemoveExistingFile()); -} - -TEST_F(HProfTest, DISABLED_ContrastString) -{ - HProfTestHelper tester("ContrastString.heapsnapshot"); - ASSERT_TRUE(tester.GenerateHeapDump(thread)); - ASSERT_TRUE(tester.ContrastJSONSectionPayload("\"strings\":[", 1 + 1)); - ASSERT_TRUE(tester.RemoveExistingFile()); -} - -TEST_F(HProfTest, DISABLED_ContrastClosure) -{ - HProfTestHelper tester("ContrastClosure.heapsnapshot"); - ASSERT_TRUE(tester.GenerateHeapDump(thread)); - ASSERT_TRUE(tester.ContrastJSONClousure()); - ASSERT_TRUE(tester.RemoveExistingFile()); -} - -TEST_F(HProfTest, DISABLED_ContrastNodeCount) -{ - HProfTestHelper tester("ContrastNodeCount.heapsnapshot"); - ASSERT_TRUE(tester.GenerateHeapDump(thread)); - ASSERT_TRUE(tester.ExtractCountFromMeta("\"node_count\":") == tester.ExtractCountFromPayload("\"nodes\":[")); - ASSERT_TRUE(tester.RemoveExistingFile()); -} - -TEST_F(HProfTest, DISABLED_ContrastEdgeCount) -{ - HProfTestHelper tester("ContrastEdgeCount.heapsnapshot"); - ASSERT_TRUE(tester.GenerateHeapDump(thread)); - ASSERT_TRUE(tester.ExtractCountFromMeta("\"edge_count\":") == tester.ExtractCountFromPayload("\"edges\":[")); - ASSERT_TRUE(tester.RemoveExistingFile()); -} - -TEST_F(HProfTest, DISABLED_ContrastTraceFunctionInfoCount) -{ - HProfTestHelper tester("ContrastTraceFunctionInfoCount.heapsnapshot"); - ASSERT_TRUE(tester.GenerateHeapDump(thread)); - ASSERT_TRUE(tester.ExtractCountFromMeta("\"trace_function_count\":") == - tester.ExtractCountFromPayload("\"trace_function_infos\":")); - ASSERT_TRUE(tester.RemoveExistingFile()); -} -} // namespace panda::test diff --git a/tests/runtime/regexp/dyn_buffer_test.cpp b/tests/runtime/regexp/dyn_buffer_test.cpp index c163e9a801a4fde69aa1f5eb120813ec450fccf8..b66315c671883f21a3765969056d459b93b0041e 100644 --- a/tests/runtime/regexp/dyn_buffer_test.cpp +++ b/tests/runtime/regexp/dyn_buffer_test.cpp @@ -31,7 +31,6 @@ public: void SetUp() override { TestHelper::CreateEcmaVMWithScope(instance, thread, scope); - chunk_ = thread->GetEcmaVM()->GetChunk(); } void TearDown() override @@ -42,12 +41,11 @@ public: PandaVM *instance; JSThread *thread; EcmaHandleScope *scope {nullptr}; - Chunk *chunk_; }; TEST_F(DynBufferTest, EmitAndGet) { - DynChunk dynChunk = DynChunk(chunk_); + DynChunk dynChunk = DynChunk(); dynChunk.EmitChar(65); dynChunk.EmitU16(66); dynChunk.EmitU32(67); @@ -65,7 +63,7 @@ TEST_F(DynBufferTest, EmitAndGet) TEST_F(DynBufferTest, EmitSelfAndGet) { - DynChunk dynChunk = DynChunk(chunk_); + DynChunk dynChunk = DynChunk(); dynChunk.EmitChar(65); dynChunk.EmitSelf(0, 1); ASSERT_EQ(dynChunk.GetSize(), 2); @@ -79,7 +77,7 @@ TEST_F(DynBufferTest, EmitSelfAndGet) TEST_F(DynBufferTest, EmitStrAndGet) { - DynChunk dynChunk = DynChunk(chunk_); + DynChunk dynChunk = DynChunk(); dynChunk.EmitStr("abc"); ASSERT_EQ(dynChunk.GetSize(), 4); ASSERT_EQ(dynChunk.GetAllocatedSize(), DynChunk::ALLOCATE_MIN_SIZE); diff --git a/tests/runtime/regexp/regexp_test.cpp b/tests/runtime/regexp/regexp_test.cpp index faa9d6ef17e7bc51f19d1907c3b40b1c08fa3e97..f54db20b8111568c29711545d6a9031d79c6aaf5 100644 --- a/tests/runtime/regexp/regexp_test.cpp +++ b/tests/runtime/regexp/regexp_test.cpp @@ -43,7 +43,6 @@ public: void SetUp() override { TestHelper::CreateEcmaVMWithScope(instance, thread, scope); - chunk_ = thread->GetEcmaVM()->GetChunk(); } void TearDown() override @@ -105,13 +104,12 @@ protected: PandaVM *instance {nullptr}; EcmaHandleScope *scope {nullptr}; JSThread *thread {nullptr}; - Chunk *chunk_ {nullptr}; }; TEST_F(RegExpTest, ParseError1) { - RegExpParser parser = RegExpParser(chunk_); - CString source("0{2,1}"); + RegExpParser parser = RegExpParser(); + PandaString source("0{2,1}"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -120,8 +118,8 @@ TEST_F(RegExpTest, ParseError1) TEST_F(RegExpTest, ParseError2) { - RegExpParser parser = RegExpParser(chunk_); - CString source("^[z-a]$"); + RegExpParser parser = RegExpParser(); + PandaString source("^[z-a]$"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -130,8 +128,8 @@ TEST_F(RegExpTest, ParseError2) TEST_F(RegExpTest, ParseError3) { - RegExpParser parser = RegExpParser(chunk_); - CString source("\\"); + RegExpParser parser = RegExpParser(); + PandaString source("\\"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -140,8 +138,8 @@ TEST_F(RegExpTest, ParseError3) TEST_F(RegExpTest, ParseError4) { - RegExpParser parser = RegExpParser(chunk_); - CString source("a**"); + RegExpParser parser = RegExpParser(); + PandaString source("a**"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -150,8 +148,8 @@ TEST_F(RegExpTest, ParseError4) TEST_F(RegExpTest, ParseError5) { - RegExpParser parser = RegExpParser(chunk_); - CString source("a***"); + RegExpParser parser = RegExpParser(); + PandaString source("a***"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -160,8 +158,8 @@ TEST_F(RegExpTest, ParseError5) TEST_F(RegExpTest, ParseError6) { - RegExpParser parser = RegExpParser(chunk_); - CString source("a**"); + RegExpParser parser = RegExpParser(); + PandaString source("a**"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -170,8 +168,8 @@ TEST_F(RegExpTest, ParseError6) TEST_F(RegExpTest, ParseError7) { - RegExpParser parser = RegExpParser(chunk_); - CString source("a++"); + RegExpParser parser = RegExpParser(); + PandaString source("a++"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -180,8 +178,8 @@ TEST_F(RegExpTest, ParseError7) TEST_F(RegExpTest, ParseError8) { - RegExpParser parser = RegExpParser(chunk_); - CString source("a+++"); + RegExpParser parser = RegExpParser(); + PandaString source("a+++"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -190,8 +188,8 @@ TEST_F(RegExpTest, ParseError8) TEST_F(RegExpTest, ParseError9) { - RegExpParser parser = RegExpParser(chunk_); - CString source("a???"); + RegExpParser parser = RegExpParser(); + PandaString source("a???"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -200,8 +198,8 @@ TEST_F(RegExpTest, ParseError9) TEST_F(RegExpTest, ParseError10) { - RegExpParser parser = RegExpParser(chunk_); - CString source("a????"); + RegExpParser parser = RegExpParser(); + PandaString source("a????"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -210,8 +208,8 @@ TEST_F(RegExpTest, ParseError10) TEST_F(RegExpTest, ParseError11) { - RegExpParser parser = RegExpParser(chunk_); - CString source("*a"); + RegExpParser parser = RegExpParser(); + PandaString source("*a"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -220,8 +218,8 @@ TEST_F(RegExpTest, ParseError11) TEST_F(RegExpTest, ParseError12) { - RegExpParser parser = RegExpParser(chunk_); - CString source("**a"); + RegExpParser parser = RegExpParser(); + PandaString source("**a"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -230,8 +228,8 @@ TEST_F(RegExpTest, ParseError12) TEST_F(RegExpTest, ParseError13) { - RegExpParser parser = RegExpParser(chunk_); - CString source("+a"); + RegExpParser parser = RegExpParser(); + PandaString source("+a"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -240,8 +238,8 @@ TEST_F(RegExpTest, ParseError13) TEST_F(RegExpTest, ParseError14) { - RegExpParser parser = RegExpParser(chunk_); - CString source("++a"); + RegExpParser parser = RegExpParser(); + PandaString source("++a"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -250,8 +248,8 @@ TEST_F(RegExpTest, ParseError14) TEST_F(RegExpTest, ParseError15) { - RegExpParser parser = RegExpParser(chunk_); - CString source("?a"); + RegExpParser parser = RegExpParser(); + PandaString source("?a"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -260,8 +258,8 @@ TEST_F(RegExpTest, ParseError15) TEST_F(RegExpTest, ParseError16) { - RegExpParser parser = RegExpParser(chunk_); - CString source("??a"); + RegExpParser parser = RegExpParser(); + PandaString source("??a"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -270,8 +268,8 @@ TEST_F(RegExpTest, ParseError16) TEST_F(RegExpTest, ParseError17) { - RegExpParser parser = RegExpParser(chunk_); - CString source("x{1}{1,}"); + RegExpParser parser = RegExpParser(); + PandaString source("x{1}{1,}"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -280,8 +278,8 @@ TEST_F(RegExpTest, ParseError17) TEST_F(RegExpTest, ParseError18) { - RegExpParser parser = RegExpParser(chunk_); - CString source("x{1,2}{1}"); + RegExpParser parser = RegExpParser(); + PandaString source("x{1,2}{1}"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -290,8 +288,8 @@ TEST_F(RegExpTest, ParseError18) TEST_F(RegExpTest, ParseError19) { - RegExpParser parser = RegExpParser(chunk_); - CString source("x{1,}{1}"); + RegExpParser parser = RegExpParser(); + PandaString source("x{1,}{1}"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -300,8 +298,8 @@ TEST_F(RegExpTest, ParseError19) TEST_F(RegExpTest, ParseError20) { - RegExpParser parser = RegExpParser(chunk_); - CString source("x{0,1}{1,}"); + RegExpParser parser = RegExpParser(); + PandaString source("x{0,1}{1,}"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -310,8 +308,8 @@ TEST_F(RegExpTest, ParseError20) TEST_F(RegExpTest, ParseError21) { - RegExpParser parser = RegExpParser(chunk_); - CString source("[b-ac-e]"); + RegExpParser parser = RegExpParser(); + PandaString source("[b-ac-e]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -320,8 +318,8 @@ TEST_F(RegExpTest, ParseError21) TEST_F(RegExpTest, ParseError22) { - RegExpParser parser = RegExpParser(chunk_); - CString source("[\\10b-G]"); + RegExpParser parser = RegExpParser(); + PandaString source("[\\10b-G]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -330,8 +328,8 @@ TEST_F(RegExpTest, ParseError22) TEST_F(RegExpTest, ParseError23) { - RegExpParser parser = RegExpParser(chunk_); - CString source("[\\0b-G]"); + RegExpParser parser = RegExpParser(); + PandaString source("[\\0b-G]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); @@ -340,8 +338,8 @@ TEST_F(RegExpTest, ParseError23) TEST_F(RegExpTest, ParseError24) { - RegExpParser parser = RegExpParser(chunk_); - CString source("("); + RegExpParser parser = RegExpParser(); + PandaString source("("); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -350,8 +348,8 @@ TEST_F(RegExpTest, ParseError24) TEST_F(RegExpTest, ParseError25) { - RegExpParser parser = RegExpParser(chunk_); - CString source(")"); + RegExpParser parser = RegExpParser(); + PandaString source(")"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -360,8 +358,8 @@ TEST_F(RegExpTest, ParseError25) TEST_F(RegExpTest, ParseError26) { - RegExpParser parser = RegExpParser(chunk_); - CString source("{"); + RegExpParser parser = RegExpParser(); + PandaString source("{"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -370,8 +368,8 @@ TEST_F(RegExpTest, ParseError26) TEST_F(RegExpTest, ParseError27) { - RegExpParser parser = RegExpParser(chunk_); - CString source("}"); + RegExpParser parser = RegExpParser(); + PandaString source("}"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -380,8 +378,8 @@ TEST_F(RegExpTest, ParseError27) TEST_F(RegExpTest, ParseError28) { - RegExpParser parser = RegExpParser(chunk_); - CString source("["); + RegExpParser parser = RegExpParser(); + PandaString source("["); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -390,8 +388,8 @@ TEST_F(RegExpTest, ParseError28) TEST_F(RegExpTest, ParseError29) { - RegExpParser parser = RegExpParser(chunk_); - CString source("]"); + RegExpParser parser = RegExpParser(); + PandaString source("]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -400,8 +398,8 @@ TEST_F(RegExpTest, ParseError29) TEST_F(RegExpTest, ParseError30) { - RegExpParser parser = RegExpParser(chunk_); - CString source("\\c"); + RegExpParser parser = RegExpParser(); + PandaString source("\\c"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -410,8 +408,8 @@ TEST_F(RegExpTest, ParseError30) TEST_F(RegExpTest, ParseError31) { - RegExpParser parser = RegExpParser(chunk_); - CString source("\\c\024"); + RegExpParser parser = RegExpParser(); + PandaString source("\\c\024"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -420,8 +418,8 @@ TEST_F(RegExpTest, ParseError31) TEST_F(RegExpTest, ParseError32) { - RegExpParser parser = RegExpParser(chunk_); - CString source("[\\c]"); + RegExpParser parser = RegExpParser(); + PandaString source("[\\c]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -430,8 +428,8 @@ TEST_F(RegExpTest, ParseError32) TEST_F(RegExpTest, ParseError33) { - RegExpParser parser = RegExpParser(chunk_); - CString source("[\\c\024]"); + RegExpParser parser = RegExpParser(); + PandaString source("[\\c\024]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -440,8 +438,8 @@ TEST_F(RegExpTest, ParseError33) TEST_F(RegExpTest, ParseError34) { - RegExpParser parser = RegExpParser(chunk_); - CString source("[\\d-a]"); + RegExpParser parser = RegExpParser(); + PandaString source("[\\d-a]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -450,8 +448,8 @@ TEST_F(RegExpTest, ParseError34) TEST_F(RegExpTest, ParseError35) { - RegExpParser parser = RegExpParser(chunk_); - CString source("[\\s-a]"); + RegExpParser parser = RegExpParser(); + PandaString source("[\\s-a]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -460,8 +458,8 @@ TEST_F(RegExpTest, ParseError35) TEST_F(RegExpTest, ParseError36) { - RegExpParser parser = RegExpParser(chunk_); - CString source("[\\s-\\w]"); + RegExpParser parser = RegExpParser(); + PandaString source("[\\s-\\w]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -470,8 +468,8 @@ TEST_F(RegExpTest, ParseError36) TEST_F(RegExpTest, ParseError37) { - RegExpParser parser = RegExpParser(chunk_); - CString source("[a-\\w]"); + RegExpParser parser = RegExpParser(); + PandaString source("[a-\\w]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -480,8 +478,8 @@ TEST_F(RegExpTest, ParseError37) TEST_F(RegExpTest, ParseError38) { - RegExpParser parser = RegExpParser(chunk_); - CString source("\\{"); + RegExpParser parser = RegExpParser(); + PandaString source("\\{"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -490,8 +488,8 @@ TEST_F(RegExpTest, ParseError38) TEST_F(RegExpTest, ParseError39) { - RegExpParser parser = RegExpParser(chunk_); - CString source("\\/"); + RegExpParser parser = RegExpParser(); + PandaString source("\\/"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -502,9 +500,9 @@ TEST_F(RegExpTest, ParseError40) { for (char cu = 0x41; cu <= 0x5a; ++cu) { if (!IsValidAlphaEscapeInAtom(cu)) { - CString source("\\"); - source += CString(&cu, 1); - RegExpParser parser = RegExpParser(chunk_); + PandaString source("\\"); + source += PandaString(&cu, 1); + RegExpParser parser = RegExpParser(); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -513,9 +511,9 @@ TEST_F(RegExpTest, ParseError40) } for (char cu = 0x61; cu <= 0x7a; ++cu) { if (!IsValidAlphaEscapeInAtom(cu)) { - CString source("\\"); - source += CString(&cu, 1); - RegExpParser parser = RegExpParser(chunk_); + PandaString source("\\"); + source += PandaString(&cu, 1); + RegExpParser parser = RegExpParser(); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -523,11 +521,11 @@ TEST_F(RegExpTest, ParseError40) } } for (char cu = 0x41; cu <= 0x5a; ++cu) { - CString source("[\\"); + PandaString source("[\\"); if (!IsValidAlphaEscapeInAtom(cu)) { - source += CString(&cu, 1); - source += CString("]"); - RegExpParser parser = RegExpParser(chunk_); + source += PandaString(&cu, 1); + source += PandaString("]"); + RegExpParser parser = RegExpParser(); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -535,11 +533,11 @@ TEST_F(RegExpTest, ParseError40) } } for (char cu = 0x61; cu <= 0x7a; ++cu) { - CString source("[\\"); + PandaString source("[\\"); if (!IsValidAlphaEscapeInAtom(cu)) { - source += CString(&cu, 1); - source += CString("]"); - RegExpParser parser = RegExpParser(chunk_); + source += PandaString(&cu, 1); + source += PandaString("]"); + RegExpParser parser = RegExpParser(); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -550,8 +548,8 @@ TEST_F(RegExpTest, ParseError40) TEST_F(RegExpTest, ParseError44) { - RegExpParser parser = RegExpParser(chunk_); - CString source("\\1"); + RegExpParser parser = RegExpParser(); + PandaString source("\\1"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -560,8 +558,8 @@ TEST_F(RegExpTest, ParseError44) TEST_F(RegExpTest, ParseError45) { - RegExpParser parser = RegExpParser(chunk_); - CString source("[\\1]"); + RegExpParser parser = RegExpParser(); + PandaString source("[\\1]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -570,8 +568,8 @@ TEST_F(RegExpTest, ParseError45) TEST_F(RegExpTest, ParseError46) { - RegExpParser parser = RegExpParser(chunk_); - CString source("\\00"); + RegExpParser parser = RegExpParser(); + PandaString source("\\00"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -580,8 +578,8 @@ TEST_F(RegExpTest, ParseError46) TEST_F(RegExpTest, ParseError47) { - RegExpParser parser = RegExpParser(chunk_); - CString source("[\\00]"); + RegExpParser parser = RegExpParser(); + PandaString source("[\\00]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -590,8 +588,8 @@ TEST_F(RegExpTest, ParseError47) TEST_F(RegExpTest, ParseNoError1) { - RegExpParser parser = RegExpParser(chunk_); - CString source("a{10,2147483648}"); // 2^31 + RegExpParser parser = RegExpParser(); + PandaString source("a{10,2147483648}"); // 2^31 parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -600,8 +598,8 @@ TEST_F(RegExpTest, ParseNoError1) TEST_F(RegExpTest, ParseNoError2) { - RegExpParser parser = RegExpParser(chunk_); - CString source("a{10,4294967306}"); // 2^32+10 + RegExpParser parser = RegExpParser(); + PandaString source("a{10,4294967306}"); // 2^32+10 parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); @@ -611,15 +609,15 @@ TEST_F(RegExpTest, ParseNoError2) TEST_F(RegExpTest, ParseAndExec1) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("ab"); + RegExpParser parser = RegExpParser(); + PandaString source("ab"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("abc"); + RegExpExecutor executor; + PandaString input("abc"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -633,15 +631,15 @@ TEST_F(RegExpTest, ParseAndExec1) TEST_F(RegExpTest, ParseAndExec2) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("(((ab)|(cd)|(de))|((ef)|(gh)|(jk)))"); + RegExpParser parser = RegExpParser(); + PandaString source("(((ab)|(cd)|(de))|((ef)|(gh)|(jk)))"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("cabd"); + RegExpExecutor executor; + PandaString input("cabd"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -664,15 +662,15 @@ TEST_F(RegExpTest, ParseAndExec2) TEST_F(RegExpTest, ParseAndExec3) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("(aa|aabaac|ba|b|c)*"); + RegExpParser parser = RegExpParser(); + PandaString source("(aa|aabaac|ba|b|c)*"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("aabaac"); + RegExpExecutor executor; + PandaString input("aabaac"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -688,15 +686,15 @@ TEST_F(RegExpTest, ParseAndExec3) TEST_F(RegExpTest, ParseAndExec4) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("a*"); + RegExpParser parser = RegExpParser(); + PandaString source("a*"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("aabaac"); + RegExpExecutor executor; + PandaString input("aabaac"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -710,15 +708,15 @@ TEST_F(RegExpTest, ParseAndExec4) TEST_F(RegExpTest, ParseAndExec5) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("a?"); + RegExpParser parser = RegExpParser(); + PandaString source("a?"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("b"); + RegExpExecutor executor; + PandaString input("b"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -732,15 +730,15 @@ TEST_F(RegExpTest, ParseAndExec5) TEST_F(RegExpTest, ParseAndExec6) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("(z)((a+)?(b+)?(c))*"); + RegExpParser parser = RegExpParser(); + PandaString source("(z)((a+)?(b+)?(c))*"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("zaacbbbcac"); + RegExpExecutor executor; + PandaString input("zaacbbbcac"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -763,15 +761,15 @@ TEST_F(RegExpTest, ParseAndExec6) TEST_F(RegExpTest, ParseAndExec7) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("^abc"); + RegExpParser parser = RegExpParser(); + PandaString source("^abc"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 4); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("ab\nabc"); + RegExpExecutor executor; + PandaString input("ab\nabc"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -785,15 +783,15 @@ TEST_F(RegExpTest, ParseAndExec7) TEST_F(RegExpTest, ParseAndExec8) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("abc$"); + RegExpParser parser = RegExpParser(); + PandaString source("abc$"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 4); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("ab\nabc"); + RegExpExecutor executor; + PandaString input("ab\nabc"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -807,15 +805,15 @@ TEST_F(RegExpTest, ParseAndExec8) TEST_F(RegExpTest, ParseAndExec9) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("er\\B"); + RegExpParser parser = RegExpParser(); + PandaString source("er\\B"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("erv"); + RegExpExecutor executor; + PandaString input("erv"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -829,15 +827,15 @@ TEST_F(RegExpTest, ParseAndExec9) TEST_F(RegExpTest, ParseAndExec10) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("d\\b"); + RegExpParser parser = RegExpParser(); + PandaString source("d\\b"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("bad good"); + RegExpExecutor executor; + PandaString input("bad good"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -851,15 +849,15 @@ TEST_F(RegExpTest, ParseAndExec10) TEST_F(RegExpTest, ParseAndExec11) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("."); + RegExpParser parser = RegExpParser(); + PandaString source("."); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("\na"); + RegExpExecutor executor; + PandaString input("\na"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -873,15 +871,15 @@ TEST_F(RegExpTest, ParseAndExec11) TEST_F(RegExpTest, ParseAndExec12) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("."); + RegExpParser parser = RegExpParser(); + PandaString source("."); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 8); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("\n"); + RegExpExecutor executor; + PandaString input("\n"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -895,15 +893,15 @@ TEST_F(RegExpTest, ParseAndExec12) TEST_F(RegExpTest, ParseAndExec13) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("abc"); + RegExpParser parser = RegExpParser(); + PandaString source("abc"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 4); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("\naabc"); + RegExpExecutor executor; + PandaString input("\naabc"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -917,15 +915,15 @@ TEST_F(RegExpTest, ParseAndExec13) TEST_F(RegExpTest, ParseAndExec14) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("abc"); + RegExpParser parser = RegExpParser(); + PandaString source("abc"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 4); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("\nbbabc"); + RegExpExecutor executor; + PandaString input("\nbbabc"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -939,15 +937,15 @@ TEST_F(RegExpTest, ParseAndExec14) TEST_F(RegExpTest, ParseAndExec15) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("a(?=a)"); + RegExpParser parser = RegExpParser(); + PandaString source("a(?=a)"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("aabc"); + RegExpExecutor executor; + PandaString input("aabc"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -961,15 +959,15 @@ TEST_F(RegExpTest, ParseAndExec15) TEST_F(RegExpTest, ParseAndExec16) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("abc"); + RegExpParser parser = RegExpParser(); + PandaString source("abc"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 2); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("ABC"); + RegExpExecutor executor; + PandaString input("ABC"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -983,15 +981,15 @@ TEST_F(RegExpTest, ParseAndExec16) TEST_F(RegExpTest, ParseAndExec17) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("a\\n"); + RegExpParser parser = RegExpParser(); + PandaString source("a\\n"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 2); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("a\n"); + RegExpExecutor executor; + PandaString input("a\n"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1004,15 +1002,15 @@ TEST_F(RegExpTest, ParseAndExec17) TEST_F(RegExpTest, ParseAndExec18) { - RegExpParser parser = RegExpParser(chunk_); - CString source("a(?=a)"); + RegExpParser parser = RegExpParser(); + PandaString source("a(?=a)"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("ababc"); + RegExpExecutor executor; + PandaString input("ababc"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_FALSE(ret); @@ -1021,15 +1019,15 @@ TEST_F(RegExpTest, ParseAndExec18) TEST_F(RegExpTest, ParseAndExec19) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("a(?!a)"); + RegExpParser parser = RegExpParser(); + PandaString source("a(?!a)"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("ababc"); + RegExpExecutor executor; + PandaString input("ababc"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1043,15 +1041,15 @@ TEST_F(RegExpTest, ParseAndExec19) TEST_F(RegExpTest, ParseAndExec20) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("(?=(a+))"); + RegExpParser parser = RegExpParser(); + PandaString source("(?=(a+))"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("baaabac"); + RegExpExecutor executor; + PandaString input("baaabac"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1067,15 +1065,15 @@ TEST_F(RegExpTest, ParseAndExec20) TEST_F(RegExpTest, ParseAndExec21) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("a(?=a(?=b))"); + RegExpParser parser = RegExpParser(); + PandaString source("a(?=a(?=b))"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("caab"); + RegExpExecutor executor; + PandaString input("caab"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1089,15 +1087,15 @@ TEST_F(RegExpTest, ParseAndExec21) TEST_F(RegExpTest, ParseAndExec22) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source(".+:"); + RegExpParser parser = RegExpParser(); + PandaString source(".+:"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("aaaa:aa"); + RegExpExecutor executor; + PandaString input("aaaa:aa"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1111,15 +1109,15 @@ TEST_F(RegExpTest, ParseAndExec22) TEST_F(RegExpTest, ParseAndExec23) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("a(?<=a(?(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("caab"); + RegExpExecutor executor; + PandaString input("caab"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1132,15 +1130,15 @@ TEST_F(RegExpTest, ParseAndExec23) TEST_F(RegExpTest, ParseAndExec24) { - RegExpParser parser = RegExpParser(chunk_); - CString source("a(?<=ab(?(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("caab"); + RegExpExecutor executor; + PandaString input("caab"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_FALSE(ret); @@ -1149,15 +1147,15 @@ TEST_F(RegExpTest, ParseAndExec24) TEST_F(RegExpTest, ParseAndExec25) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("(?<=(ab))"); + RegExpParser parser = RegExpParser(); + PandaString source("(?<=(ab))"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("cabab"); + RegExpExecutor executor; + PandaString input("cabab"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1173,15 +1171,15 @@ TEST_F(RegExpTest, ParseAndExec25) TEST_F(RegExpTest, ParseAndExec26) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("[a-z]"); + RegExpParser parser = RegExpParser(); + PandaString source("[a-z]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 2); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("A"); + RegExpExecutor executor; + PandaString input("A"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1195,15 +1193,15 @@ TEST_F(RegExpTest, ParseAndExec26) TEST_F(RegExpTest, ParseAndExec27) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("[^a-b]"); + RegExpParser parser = RegExpParser(); + PandaString source("[^a-b]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 2); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("Z"); + RegExpExecutor executor; + PandaString input("Z"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1217,15 +1215,15 @@ TEST_F(RegExpTest, ParseAndExec27) TEST_F(RegExpTest, ParseAndExec28) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("\\s"); + RegExpParser parser = RegExpParser(); + PandaString source("\\s"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("\n"); + RegExpExecutor executor; + PandaString input("\n"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1239,15 +1237,15 @@ TEST_F(RegExpTest, ParseAndExec28) TEST_F(RegExpTest, ParseAndExec29) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("()|"); + RegExpParser parser = RegExpParser(); + PandaString source("()|"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input(""); + RegExpExecutor executor; + PandaString input(""); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1262,15 +1260,15 @@ TEST_F(RegExpTest, ParseAndExec29) TEST_F(RegExpTest, ParseAndExec30) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("|()"); + RegExpParser parser = RegExpParser(); + PandaString source("|()"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input(""); + RegExpExecutor executor; + PandaString input(""); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1285,14 +1283,14 @@ TEST_F(RegExpTest, ParseAndExec30) TEST_F(RegExpTest, ParseAndExec31) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("a(a|b)\\1"); + RegExpParser parser = RegExpParser(); + PandaString source("a(a|b)\\1"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 2); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("aabb"); + RegExpExecutor executor; + PandaString input("aabb"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1307,14 +1305,14 @@ TEST_F(RegExpTest, ParseAndExec31) TEST_F(RegExpTest, ParseAndExec32) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("(a(a|b))\\2"); + RegExpParser parser = RegExpParser(); + PandaString source("(a(a|b))\\2"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 2); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("aabb"); + RegExpExecutor executor; + PandaString input("aabb"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1331,14 +1329,14 @@ TEST_F(RegExpTest, ParseAndExec32) TEST_F(RegExpTest, ParseAndExec33) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("qya+"); + RegExpParser parser = RegExpParser(); + PandaString source("qya+"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 2); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("qyqya"); + RegExpExecutor executor; + PandaString input("qyqya"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1351,14 +1349,14 @@ TEST_F(RegExpTest, ParseAndExec33) TEST_F(RegExpTest, ParseAndExec34) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("qy(?=\\s+)"); + RegExpParser parser = RegExpParser(); + PandaString source("qy(?=\\s+)"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 2); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("qyqy "); + RegExpExecutor executor; + PandaString input("qyqy "); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1371,14 +1369,14 @@ TEST_F(RegExpTest, ParseAndExec34) TEST_F(RegExpTest, ParseAndExec35) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("(\\d{4})-(\\d{2})-(\\d{2})"); + RegExpParser parser = RegExpParser(); + PandaString source("(\\d{4})-(\\d{2})-(\\d{2})"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 2); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("xx2021-01-09"); + RegExpExecutor executor; + PandaString input("xx2021-01-09"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1397,14 +1395,14 @@ TEST_F(RegExpTest, ParseAndExec35) TEST_F(RegExpTest, ParseAndExec36) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("quick\\s(brown).+?(jumps)"); + RegExpParser parser = RegExpParser(); + PandaString source("quick\\s(brown).+?(jumps)"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 2); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("The Quick Brown Fox Jumps Over The Lazy Dog"); + RegExpExecutor executor; + PandaString input("The Quick Brown Fox Jumps Over The Lazy Dog"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1421,14 +1419,14 @@ TEST_F(RegExpTest, ParseAndExec36) TEST_F(RegExpTest, ParseAndExec37) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("(ab){1,2}?c"); + RegExpParser parser = RegExpParser(); + PandaString source("(ab){1,2}?c"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 2); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("abABc"); + RegExpExecutor executor; + PandaString input("abABc"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1443,14 +1441,14 @@ TEST_F(RegExpTest, ParseAndExec37) TEST_F(RegExpTest, ParseAndExec38) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("^(([a-z]+)*[a-z]\\.)+[a-z]{2,}$"); + RegExpParser parser = RegExpParser(); + PandaString source("^(([a-z]+)*[a-z]\\.)+[a-z]{2,}$"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("www.netscape.com"); + RegExpExecutor executor; + PandaString input("www.netscape.com"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1467,14 +1465,14 @@ TEST_F(RegExpTest, ParseAndExec38) TEST_F(RegExpTest, ParseAndExec39) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("(a*)b\\1+"); + RegExpParser parser = RegExpParser(); + PandaString source("(a*)b\\1+"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("baaaac"); + RegExpExecutor executor; + PandaString input("baaaac"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1489,14 +1487,14 @@ TEST_F(RegExpTest, ParseAndExec39) TEST_F(RegExpTest, ParseAndExec40) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("a*?"); + RegExpParser parser = RegExpParser(); + PandaString source("a*?"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("ab"); + RegExpExecutor executor; + PandaString input("ab"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1509,14 +1507,14 @@ TEST_F(RegExpTest, ParseAndExec40) TEST_F(RegExpTest, ParseAndExec41) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("(.*?)a(?!(a+)b\\2c)\\2(.*)"); + RegExpParser parser = RegExpParser(); + PandaString source("(.*?)a(?!(a+)b\\2c)\\2(.*)"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("baaabaac"); + RegExpExecutor executor; + PandaString input("baaabaac"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1534,14 +1532,14 @@ TEST_F(RegExpTest, ParseAndExec41) TEST_F(RegExpTest, ParseAndExec42) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("[a-c\\d]+"); + RegExpParser parser = RegExpParser(); + PandaString source("[a-c\\d]+"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("\n\n\\abc324234"); + RegExpExecutor executor; + PandaString input("\n\n\\abc324234"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1554,14 +1552,14 @@ TEST_F(RegExpTest, ParseAndExec42) TEST_F(RegExpTest, ParseAndExec43) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("[\\d][\n][^\\d]"); + RegExpParser parser = RegExpParser(); + PandaString source("[\\d][\n][^\\d]"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("line1\nline2"); + RegExpExecutor executor; + PandaString input("line1\nline2"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1574,14 +1572,14 @@ TEST_F(RegExpTest, ParseAndExec43) TEST_F(RegExpTest, ParseAndExec44) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source(".[\b]."); + RegExpParser parser = RegExpParser(); + PandaString source(".[\b]."); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("abc\bdef"); + RegExpExecutor executor; + PandaString input("abc\bdef"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1594,14 +1592,14 @@ TEST_F(RegExpTest, ParseAndExec44) TEST_F(RegExpTest, ParseAndExec45) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("[^\b]+"); + RegExpParser parser = RegExpParser(); + PandaString source("[^\b]+"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("easy\bto\u0008ride"); + RegExpExecutor executor; + PandaString input("easy\bto\u0008ride"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1614,14 +1612,14 @@ TEST_F(RegExpTest, ParseAndExec45) TEST_F(RegExpTest, ParseAndExec46) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("([\\S]+([ \t]+[\\S]+)*)[ \t]*=[ \t]*[\\S]+"); + RegExpParser parser = RegExpParser(); + PandaString source("([\\S]+([ \t]+[\\S]+)*)[ \t]*=[ \t]*[\\S]+"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("Course_Creator = Test"); + RegExpExecutor executor; + PandaString input("Course_Creator = Test"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1638,14 +1636,14 @@ TEST_F(RegExpTest, ParseAndExec46) TEST_F(RegExpTest, ParseAndExec47) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("[^o]t\\b"); + RegExpParser parser = RegExpParser(); + PandaString source("[^o]t\\b"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 2); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("pilOt\nsoviet robot\topenoffice"); + RegExpExecutor executor; + PandaString input("pilOt\nsoviet robot\topenoffice"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1658,14 +1656,14 @@ TEST_F(RegExpTest, ParseAndExec47) TEST_F(RegExpTest, ParseAndExec49) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("(a(b)\\4(5)(5))"); + RegExpParser parser = RegExpParser(); + PandaString source("(a(b)\\4(5)(5))"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 2); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("ab55"); + RegExpExecutor executor; + PandaString input("ab55"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1686,14 +1684,14 @@ TEST_F(RegExpTest, ParseAndExec49) TEST_F(RegExpTest, ParseAndExec50) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("(?\\d{4})-(?\\d{2}-(?\\d\\d))"); + RegExpParser parser = RegExpParser(); + PandaString source("(?\\d{4})-(?\\d{2}-(?\\d\\d))"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("2020-12-31"); + RegExpExecutor executor; + PandaString input("2020-12-31"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1711,13 +1709,13 @@ TEST_F(RegExpTest, ParseAndExec50) TEST_F(RegExpTest, ParseAndExec51) { - RegExpParser parser = RegExpParser(chunk_); - CString source("\\u0000"); + RegExpParser parser = RegExpParser(); + PandaString source("\\u0000"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); + RegExpExecutor executor; std::u16string input(u"\u0000"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length() + 1, parser.GetOriginBuffer(), true); @@ -1729,14 +1727,14 @@ TEST_F(RegExpTest, ParseAndExec51) TEST_F(RegExpTest, ParseAndExec52) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("(aa).+\\1"); + RegExpParser parser = RegExpParser(); + PandaString source("(aa).+\\1"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("aabcdaabcd"); + RegExpExecutor executor; + PandaString input("aabcdaabcd"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); @@ -1751,13 +1749,13 @@ TEST_F(RegExpTest, ParseAndExec52) TEST_F(RegExpTest, ParseAndExec53) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("\\x01"); + RegExpParser parser = RegExpParser(); + PandaString source("\\x01"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); + RegExpExecutor executor; std::u16string input(u"\u0001"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer(), true); @@ -1770,14 +1768,14 @@ TEST_F(RegExpTest, ParseAndExec53) TEST_F(RegExpTest, ParseAndExec54) { - RegExpParser parser = RegExpParser(chunk_); - CString source("\\bot"); + RegExpParser parser = RegExpParser(); + PandaString source("\\bot"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("pilot\nsoviet robot\topenoffice"); + RegExpExecutor executor; + PandaString input("pilot\nsoviet robot\topenoffice"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer(), false); ASSERT_FALSE(ret); @@ -1786,14 +1784,14 @@ TEST_F(RegExpTest, ParseAndExec54) TEST_F(RegExpTest, ParseAndExec55) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("e\\b"); + RegExpParser parser = RegExpParser(); + PandaString source("e\\b"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("c\u0065"); + RegExpExecutor executor; + PandaString input("c\u0065"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer(), false); ASSERT_TRUE(ret); @@ -1806,13 +1804,13 @@ TEST_F(RegExpTest, ParseAndExec55) TEST_F(RegExpTest, ParseAndExec56) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("a啊"); + RegExpParser parser = RegExpParser(); + PandaString source("a啊"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); + RegExpExecutor executor; std::u16string input(u"a啊"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.length(), parser.GetOriginBuffer(), true); @@ -1825,13 +1823,13 @@ TEST_F(RegExpTest, ParseAndExec56) TEST_F(RegExpTest, ParseAndExec57) { - RegExpParser parser = RegExpParser(chunk_); - CString source("\\udf06"); + RegExpParser parser = RegExpParser(); + PandaString source("\\udf06"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 16); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); + RegExpExecutor executor; char16_t data[] = {0xd834, 0xdf06}; bool ret = executor.Execute(reinterpret_cast(data), 0, 2, parser.GetOriginBuffer(), true); ASSERT_FALSE(ret); @@ -1840,13 +1838,13 @@ TEST_F(RegExpTest, ParseAndExec57) TEST_F(RegExpTest, ParseAndExec58) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("\\udf06"); + RegExpParser parser = RegExpParser(); + PandaString source("\\udf06"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); + RegExpExecutor executor; char16_t data[] = {0xd834, 0xdf06}; bool ret = executor.Execute(reinterpret_cast(data), 0, 2, parser.GetOriginBuffer(), true); ASSERT_TRUE(ret); @@ -1860,15 +1858,15 @@ TEST_F(RegExpTest, ParseAndExec58) TEST_F(RegExpTest, ParseAndExec59) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - RegExpParser parser = RegExpParser(chunk_); - CString source("\\v"); + RegExpParser parser = RegExpParser(); + PandaString source("\\v"); parser.Init(const_cast(reinterpret_cast(source.c_str())), source.size(), 0); parser.Parse(); bool parseResult = parser.IsError(); ASSERT_FALSE(parseResult); - RegExpExecutor executor(chunk_); - CString input("\u000B"); + RegExpExecutor executor; + PandaString input("\u000B"); bool ret = executor.Execute(reinterpret_cast(input.c_str()), 0, input.size(), parser.GetOriginBuffer()); ASSERT_TRUE(ret); diff --git a/tests/runtime/snapshot/snapshot_test.cpp b/tests/runtime/snapshot/snapshot_test.cpp deleted file mode 100644 index c531d65c500a63a167e76dbf7db561470cb62809..0000000000000000000000000000000000000000 --- a/tests/runtime/snapshot/snapshot_test.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "gtest/gtest.h" -#include "test_helper.h" - -#include "plugins/ecmascript/runtime/ecma_vm.h" -#include "plugins/ecmascript/runtime/global_env.h" -#include "plugins/ecmascript/runtime/js_thread.h" -#include "include/runtime.h" -#include "plugins/ecmascript/runtime/js_handle.h" -#include "plugins/ecmascript/runtime/snapshot/mem/snapshot.h" -#include "plugins/ecmascript/runtime/js_hclass.h" -#include "plugins/ecmascript/runtime/object_factory.h" - -using namespace panda::coretypes; -using namespace panda::ecmascript; - -namespace panda::test { -class SnapShotTest : public testing::Test { -public: - void SetUp() override - { - TestHelper::CreateEcmaVMWithScope(instance, thread, scope); - } - - void TearDown() override - { - TestHelper::DestroyEcmaVMWithScope(instance, scope); - } - - PandaVM *instance {nullptr}; - EcmaHandleScope *scope {nullptr}; - JSThread *thread; -}; - -TEST_F(SnapShotTest, Serialize) {} -} // namespace panda::test