From 748f52ccf6ce00db478eb85bdb835969cc70ad01 Mon Sep 17 00:00:00 2001 From: Artem Udovichenko Date: Sat, 10 Dec 2022 14:42:48 +0300 Subject: [PATCH] Use handles in FastRuntimeStub * Some FastRuntimeStub's methods accept handles now * Add asserts that no GC happens in critical pathes * Remove all CSA suppressions from fast_runtime_stub-inl.h * Fix CSA issues in TypedArray Change-Id: I2d24621df47068762823b911311d7e958ac65c7c Signed-off-by: Artem Udovichenko --- runtime/CMakeLists.txt | 2 +- runtime/base/json_parser.h | 9 +- runtime/base/json_stringifier.cpp | 5 +- runtime/base/typed_array_helper.cpp | 2 +- runtime/builtins/builtins_arraybuffer.cpp | 6 +- runtime/builtins/builtins_arraybuffer.h | 2 +- runtime/builtins/builtins_dataview.cpp | 2 +- runtime/builtins/builtins_object.cpp | 7 +- runtime/builtins/builtins_regexp.cpp | 100 +++---- runtime/builtins/builtins_typedarray.cpp | 14 +- runtime/global_env_constants.cpp | 3 +- runtime/global_env_constants.h | 3 +- runtime/ic/ic_runtime_stub-inl.h | 1 + runtime/interpreter/fast_runtime_stub-inl.h | 166 ++++++------ runtime/interpreter/fast_runtime_stub.h | 24 +- runtime/intrinsics-inl.h | 277 ++++++++++---------- runtime/js_array.cpp | 5 +- runtime/js_handle.h | 10 + runtime/js_object.cpp | 5 +- runtime/js_regexp_iterator.cpp | 5 +- runtime/js_typed_array.cpp | 23 +- 21 files changed, 325 insertions(+), 346 deletions(-) diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 34faeb891..3652b3dcd 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -347,4 +347,4 @@ add_merge_plugin(PLUGIN_NAME "clear_profile.h" add_merge_plugin(PLUGIN_NAME "profiling_includes.h" INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/profiling/plugin_includes.h") add_merge_plugin(PLUGIN_NAME "profiling_includes_disasm.h" - INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/profiling/plugin_includes_disasm.h") \ No newline at end of file + INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/profiling/plugin_includes_disasm.h") diff --git a/runtime/base/json_parser.h b/runtime/base/json_parser.h index fd6644b0f..53315527a 100644 --- a/runtime/base/json_parser.h +++ b/runtime/base/json_parser.h @@ -311,6 +311,7 @@ private: } current_++; + [[maybe_unused]] EcmaHandleScope handle_scope(thread_); JSHandle arr = factory_->NewJSArray(); if (*current_ == ']') { return arr.GetTaggedValue(); @@ -342,6 +343,7 @@ private: THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON", JSTaggedValue::Exception()); } + [[maybe_unused]] EcmaHandleScope handle_scope(thread_); JSHandle proto = env_->GetObjectFunction(); JSHandle result = factory_->NewJSObjectByConstructor(JSHandle(proto), proto); current_++; @@ -350,7 +352,7 @@ private: } JSMutableHandle keyHandle(thread_, JSTaggedValue::Undefined()); - JSTaggedValue value; + JSMutableHandle value(thread_, JSTaggedValue::Undefined()); while (current_ <= range_) { SkipStartWhiteSpace(); if (*current_ == '"') { @@ -367,9 +369,8 @@ private: } else { THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON", JSTaggedValue::Exception()); } - value = ParseJSONText(); - FastRuntimeStub::SetPropertyByValue(thread_, result.GetTaggedValue(), keyHandle.GetTaggedValue(), - value); + value.Update(ParseJSONText()); + FastRuntimeStub::SetPropertyByValue(thread_, JSHandle(result), keyHandle, value); GetNextNonSpaceChar(); if (*current_ == ',') { current_++; diff --git a/runtime/base/json_stringifier.cpp b/runtime/base/json_stringifier.cpp index 71bf9371e..088142db4 100644 --- a/runtime/base/json_stringifier.cpp +++ b/runtime/base/json_stringifier.cpp @@ -297,8 +297,7 @@ JSTaggedValue JsonStringifier::GetSerializeValue(const JSHandle & if (value->IsECMAObject()) { // a. Let toJSON be Get(value, "toJSON"). JSHandle toJson = thread_->GlobalConstants()->GetHandledToJsonString(); - JSHandle toJsonFun( - thread_, FastRuntimeStub::FastGetPropertyByValue(thread_, tagValue, toJson.GetTaggedValue())); + JSHandle toJsonFun(thread_, FastRuntimeStub::FastGetPropertyByValue(thread_, value, toJson)); // b. ReturnIfAbrupt(toJSON). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); // Reread tagValue because GC may move it in FastRuntimeStub::FastGetPropertyByValue @@ -477,7 +476,7 @@ bool JsonStringifier::SerializeJSONObject(const JSHandle &value, uint32_t propLen = propList_.size(); for (uint32_t i = 0; i < propLen; i++) { JSTaggedValue tagVal = - FastRuntimeStub::FastGetPropertyByValue(thread_, obj.GetTaggedValue(), propList_[i].GetTaggedValue()); + FastRuntimeStub::FastGetPropertyByValue(thread_, JSHandle(obj), propList_[i]); handleValue_.Update(tagVal); JSTaggedValue serializeValue = GetSerializeValue(value, propList_[i], handleValue_, replacer); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false); diff --git a/runtime/base/typed_array_helper.cpp b/runtime/base/typed_array_helper.cpp index bb191f07b..458188ae8 100644 --- a/runtime/base/typed_array_helper.cpp +++ b/runtime/base/typed_array_helper.cpp @@ -233,7 +233,7 @@ JSTaggedValue TypedArrayHelper::CreateFromTypedArray(EcmaRuntimeCallInfo *argv, for (int32_t count = elementLength; count > 0; count--) { // i. Let value be GetValueFromBuffer(srcData, srcByteIndex, srcType, true, Unordered). JSTaggedValue taggedData = - BuiltinsArrayBuffer::GetValueFromBuffer(thread, srcData.GetTaggedValue(), srcByteIndex, srcType, true); + BuiltinsArrayBuffer::GetValueFromBuffer(thread, srcData, srcByteIndex, srcType, true); value.Update(taggedData); // ii. Perform SetValueInBuffer(data, targetByteIndex, elementType, value, true, Unordered). BuiltinsArrayBuffer::SetValueInBuffer(thread, data, targetByteIndex, elementType, value, true); diff --git a/runtime/builtins/builtins_arraybuffer.cpp b/runtime/builtins/builtins_arraybuffer.cpp index b38235ffe..dc691d52d 100644 --- a/runtime/builtins/builtins_arraybuffer.cpp +++ b/runtime/builtins/builtins_arraybuffer.cpp @@ -321,10 +321,10 @@ JSTaggedValue BuiltinsArrayBuffer::CloneArrayBuffer(JSThread *thread, const JSHa // 24.1.1.5 // NOLINTNEXTLINE(readability-function-size) -JSTaggedValue BuiltinsArrayBuffer::GetValueFromBuffer(JSThread *thread, JSTaggedValue arrBuf, int32_t byteIndex, - DataViewType type, bool littleEndian) +JSTaggedValue BuiltinsArrayBuffer::GetValueFromBuffer(JSThread *thread, JSHandle arrBuf, + int32_t byteIndex, DataViewType type, bool littleEndian) { - JSArrayBuffer *jsArrayBuffer = JSArrayBuffer::Cast(arrBuf.GetTaggedObject()); + JSArrayBuffer *jsArrayBuffer = JSArrayBuffer::Cast(arrBuf->GetTaggedObject()); JSTaggedValue data = jsArrayBuffer->GetArrayBufferData(); void *pointer = JSNativePointer::Cast(data.GetTaggedObject())->GetExternalPointer(); auto *block = reinterpret_cast(pointer); diff --git a/runtime/builtins/builtins_arraybuffer.h b/runtime/builtins/builtins_arraybuffer.h index dc20d1ae7..1e63cf59f 100644 --- a/runtime/builtins/builtins_arraybuffer.h +++ b/runtime/builtins/builtins_arraybuffer.h @@ -61,7 +61,7 @@ public: // 24.1.1.2 IsDetachedBuffer(arrayBuffer) static bool IsDetachedBuffer(JSTaggedValue arrayBuffer); // 24.1.1.5 GetValueFromBuffer ( arrayBuffer, byteIndex, type, isLittleEndian ) - static JSTaggedValue GetValueFromBuffer(JSThread *thread, JSTaggedValue arrBuf, int32_t byteIndex, + static JSTaggedValue GetValueFromBuffer(JSThread *thread, JSHandle arrBuf, int32_t byteIndex, DataViewType type, bool littleEndian); // 24.1.1.6 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isLittleEndian ) static JSTaggedValue SetValueInBuffer(JSThread *thread, JSHandle arrBuf, int32_t byteIndex, diff --git a/runtime/builtins/builtins_dataview.cpp b/runtime/builtins/builtins_dataview.cpp index 64925d13d..4fc8f1016 100644 --- a/runtime/builtins/builtins_dataview.cpp +++ b/runtime/builtins/builtins_dataview.cpp @@ -386,7 +386,7 @@ JSTaggedValue BuiltinsDataView::GetViewValue(JSThread *thread, const JSHandleGetViewedArrayBuffer(); + JSHandle buffer(thread, dataView->GetViewedArrayBuffer()); return BuiltinsArrayBuffer::GetValueFromBuffer(thread, buffer, bufferIndex, type, isLittleEndian); } } diff --git a/runtime/builtins/builtins_object.cpp b/runtime/builtins/builtins_object.cpp index b193d8a0c..0ef7df546 100644 --- a/runtime/builtins/builtins_object.cpp +++ b/runtime/builtins/builtins_object.cpp @@ -83,6 +83,7 @@ JSTaggedValue BuiltinsObject::Assign(EcmaRuntimeCallInfo *argv) // ii.Let keys be from.[[OwnPropertyKeys]](). // iii.ReturnIfAbrupt(keys). JSMutableHandle key(thread, JSTaggedValue::Undefined()); + JSMutableHandle value(thread, JSTaggedValue::Undefined()); for (uint32_t i = 1; i < numArgs; i++) { JSHandle source = GetCallArg(argv, i); if (!source->IsNull() && !source->IsUndefined()) { @@ -110,13 +111,11 @@ JSTaggedValue BuiltinsObject::Assign(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (success && desc.IsEnumerable()) { - JSTaggedValue value = - FastRuntimeStub::FastGetPropertyByValue(thread, from.GetTaggedValue(), key.GetTaggedValue()); + value.Update(FastRuntimeStub::FastGetPropertyByValue(thread, JSHandle(from), key)); // ReturnIfAbrupt(prop_value) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - FastRuntimeStub::FastSetPropertyByValue(thread, toAssign.GetTaggedValue(), key.GetTaggedValue(), - value); + FastRuntimeStub::FastSetPropertyByValue(thread, JSHandle(toAssign), key, value); // ReturnIfAbrupt(status) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } diff --git a/runtime/builtins/builtins_regexp.cpp b/runtime/builtins/builtins_regexp.cpp index 6537673c0..53738fb34 100644 --- a/runtime/builtins/builtins_regexp.cpp +++ b/runtime/builtins/builtins_regexp.cpp @@ -63,8 +63,8 @@ JSTaggedValue BuiltinsRegExp::RegExpConstructor(EcmaRuntimeCallInfo *argv) // 4.b If patternIsRegExp is true and flags is undefined if (patternIsRegExp && flags->IsUndefined()) { // 4.b.i Let patternConstructor be Get(pattern, "constructor"). - JSTaggedValue patternConstructor = FastRuntimeStub::FastGetPropertyByValue( - thread, pattern.GetTaggedValue(), constructorString.GetTaggedValue()); + JSTaggedValue patternConstructor = + FastRuntimeStub::FastGetPropertyByValue(thread, pattern, constructorString); // 4.b.ii ReturnIfAbrupt(patternConstructor). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 4.b.iii If SameValue(new_target, patternConstructor) is true, return pattern. @@ -434,8 +434,7 @@ JSTaggedValue BuiltinsRegExp::Match(EcmaRuntimeCallInfo *argv) // 5. Let global be ToBoolean(Get(rx, "global")). JSHandle global = globalConst->GetHandledGlobalString(); - JSTaggedValue globalValue = - FastRuntimeStub::FastGetPropertyByValue(thread, thisObj.GetTaggedValue(), global.GetTaggedValue()); + JSTaggedValue globalValue = FastRuntimeStub::FastGetPropertyByValue(thread, thisObj, global); // 6. ReturnIfAbrupt(global). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -472,16 +471,15 @@ JSTaggedValue BuiltinsRegExp::Match(EcmaRuntimeCallInfo *argv) // 8. Else global is true // a. Let fullUnicode be ToBoolean(Get(rx, "unicode")). JSHandle unicode = globalConst->GetHandledUnicodeString(); - JSTaggedValue uincodeValue = - FastRuntimeStub::FastGetPropertyByValue(thread, thisObj.GetTaggedValue(), unicode.GetTaggedValue()); + JSTaggedValue uincodeValue = FastRuntimeStub::FastGetPropertyByValue(thread, thisObj, unicode); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); bool fullUnicode = uincodeValue.ToBoolean(); // b. ReturnIfAbrupt(fullUnicode) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // c. Let setStatus be Set(rx, "lastIndex", 0, true). JSHandle lastIndexString(globalConst->GetHandledLastIndexString()); - FastRuntimeStub::FastSetPropertyByValue(thread, thisObj.GetTaggedValue(), lastIndexString.GetTaggedValue(), - JSTaggedValue(0)); + FastRuntimeStub::FastSetPropertyByValue(thread, JSHandle(thisObj), lastIndexString, + thread->GlobalConstants()->GetHandledZero()); // d. ReturnIfAbrupt(setStatus). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // e. Let A be ArrayCreate(0). @@ -513,8 +511,7 @@ JSTaggedValue BuiltinsRegExp::Match(EcmaRuntimeCallInfo *argv) // iv. Else result is not null, // 1. Let matchStr be ToString(Get(result, "0")). JSHandle zeroString = globalConst->GetHandledZeroString(); - JSTaggedValue matchVal = - FastRuntimeStub::FastGetPropertyByValue(thread, result.GetTaggedValue(), zeroString.GetTaggedValue()); + JSTaggedValue matchVal = FastRuntimeStub::FastGetPropertyByValue(thread, result, zeroString); JSHandle matchStr(thread, matchVal); JSHandle matchString = JSTaggedValue::ToString(thread, matchStr); // 2. ReturnIfAbrupt(matchStr). @@ -525,8 +522,7 @@ JSTaggedValue BuiltinsRegExp::Match(EcmaRuntimeCallInfo *argv) // 5. If matchStr is the empty String, then if (JSTaggedValue::ToString(thread, matchValue)->GetLength() == 0) { // a. Let thisIndex be ToLength(Get(rx, "lastIndex")). - JSTaggedValue lastIndex = FastRuntimeStub::FastGetPropertyByValue(thread, thisObj.GetTaggedValue(), - lastIndexString.GetTaggedValue()); + JSTaggedValue lastIndex = FastRuntimeStub::FastGetPropertyByValue(thread, thisObj, lastIndexString); JSHandle lastIndexHandle(thread, lastIndex); JSTaggedNumber thisIndex = JSTaggedValue::ToLength(thread, lastIndexHandle); // b. ReturnIfAbrupt(thisIndex). @@ -534,8 +530,8 @@ JSTaggedValue BuiltinsRegExp::Match(EcmaRuntimeCallInfo *argv) // c. Let nextIndex be AdvanceStringIndex(S, thisIndex, fullUnicode). // d. Let setStatus be Set(rx, "lastIndex", nextIndex, true). auto nextIndex = JSTaggedValue(AdvanceStringIndex(string, thisIndex.GetNumber(), fullUnicode)); - FastRuntimeStub::FastSetPropertyByValue(thread, thisObj.GetTaggedValue(), lastIndexString.GetTaggedValue(), - nextIndex); + FastRuntimeStub::FastSetPropertyByValue(thread, JSHandle(thisObj), lastIndexString, + HandleFromLocal(&nextIndex)); // e. ReturnIfAbrupt(setStatus). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } @@ -593,8 +589,7 @@ JSTaggedValue BuiltinsRegExp::MatchAll(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 8. Perform ? Set(matcher, "lastIndex", lastIndex, true). - FastRuntimeStub::FastSetPropertyByValue(thread, matcherHandle.GetTaggedValue(), lastIndexString.GetTaggedValue(), - thisLastIndex); + FastRuntimeStub::FastSetPropertyByValue(thread, matcherHandle, lastIndexString, HandleFromLocal(&thisLastIndex)); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 9. If flags contains "g", let global be true. @@ -637,8 +632,7 @@ JSTaggedValue BuiltinsRegExp::RegExpReplaceFast(JSThread *thread, JSHandle(thisIndex.GetInt()); } else { @@ -703,8 +697,8 @@ JSTaggedValue BuiltinsRegExp::RegExpReplaceFast(JSThread *thread, JSHandle(regexp), lastIndexHandle, + thread->GlobalConstants()->GetHandledZero()); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } break; @@ -718,8 +712,9 @@ JSTaggedValue BuiltinsRegExp::RegExpReplaceFast(JSThread *thread, JSHandle(regexp), lastIndexHandle, + HandleFromLocal(&lastIndexValue)); // b. ReturnIfAbrupt(setStatus). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); break; @@ -776,8 +771,7 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) // 8. Let global be ToBoolean(Get(rx, "global")). ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle global = globalConst->GetHandledGlobalString(); - JSTaggedValue globalValue = - FastRuntimeStub::FastGetPropertyByValue(thread, thisObj.GetTaggedValue(), global.GetTaggedValue()); + JSTaggedValue globalValue = FastRuntimeStub::FastGetPropertyByValue(thread, thisObj, global); // 9. ReturnIfAbrupt(global). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); bool isGlobal = globalValue.ToBoolean(); @@ -787,15 +781,14 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) if (isGlobal) { // a. Let fullUnicode be ToBoolean(Get(rx, "unicode")). JSHandle unicode = globalConst->GetHandledUnicodeString(); - JSTaggedValue fullUnicodeTag = - FastRuntimeStub::FastGetPropertyByValue(thread, thisObj.GetTaggedValue(), unicode.GetTaggedValue()); + JSTaggedValue fullUnicodeTag = FastRuntimeStub::FastGetPropertyByValue(thread, thisObj, unicode); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); fullUnicode = fullUnicodeTag.ToBoolean(); // b. ReturnIfAbrupt(fullUnicode). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // c. Let setStatus be Set(rx, "lastIndex", 0, true). - FastRuntimeStub::FastSetPropertyByValue(thread, thisObj.GetTaggedValue(), lastIndex.GetTaggedValue(), - JSTaggedValue(0)); + FastRuntimeStub::FastSetPropertyByValue(thread, thisObj, lastIndex, + thread->GlobalConstants()->GetHandledZero()); // d. ReturnIfAbrupt(setStatus). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } @@ -863,8 +856,7 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) break; } // iii. Else, 1. Let matchStr be ToString(Get(result, "0")). - JSTaggedValue getMatchVal = - FastRuntimeStub::FastGetPropertyByValue(thread, execResult.GetTaggedValue(), matchedStr.GetTaggedValue()); + JSTaggedValue getMatchVal = FastRuntimeStub::FastGetPropertyByValue(thread, execResult, matchedStr); JSHandle getMatch(thread, getMatchVal); JSHandle matchString = JSTaggedValue::ToString(thread, getMatch); // 2. ReturnIfAbrupt(matchStr). @@ -872,8 +864,7 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) // 3. If matchStr is the empty String, then if (matchString->GetLength() == 0) { // a. Let thisIndex be ToLength(Get(rx, "lastIndex")). - JSTaggedValue thisIndexVal = - FastRuntimeStub::FastGetPropertyByValue(thread, thisObj.GetTaggedValue(), lastIndex.GetTaggedValue()); + JSTaggedValue thisIndexVal = FastRuntimeStub::FastGetPropertyByValue(thread, thisObj, lastIndex); JSHandle thisIndexHandle(thread, thisIndexVal); uint32_t thisIndex = 0; if (thisIndexHandle->IsInt()) { @@ -888,8 +879,7 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) uint32_t nextIndex = AdvanceStringIndex(inputStr, thisIndex, fullUnicode); nextIndexHandle.Update(JSTaggedValue(nextIndex)); // d. Let setStatus be Set(rx, "lastIndex", nextIndex, true). - FastRuntimeStub::FastSetPropertyByValue(thread, thisObj.GetTaggedValue(), lastIndex.GetTaggedValue(), - nextIndexHandle.GetTaggedValue()); + FastRuntimeStub::FastSetPropertyByValue(thread, thisObj, lastIndex, nextIndexHandle); // e. ReturnIfAbrupt(setStatus). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } @@ -907,8 +897,7 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) resultValues.Update(FastRuntimeStub::FastGetPropertyByIndex(thread, resultsList.GetTaggedValue(), i)); // a. Let nCaptures be ToLength(Get(result, "length")). JSHandle lengthHandle = globalConst->GetHandledLengthString(); - ncapturesHandle.Update(FastRuntimeStub::FastGetPropertyByValue(thread, resultValues.GetTaggedValue(), - lengthHandle.GetTaggedValue())); + ncapturesHandle.Update(FastRuntimeStub::FastGetPropertyByValue(thread, resultValues, lengthHandle)); uint32_t ncaptures = JSTaggedValue::ToUint32(thread, ncapturesHandle); // b. ReturnIfAbrupt(nCaptures). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -924,8 +913,7 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) uint32_t matchLength = matchString->GetLength(); // g. Let position be ToInteger(Get(result, "index")). JSHandle resultIndex = globalConst->GetHandledIndexString(); - JSTaggedValue positionTag = FastRuntimeStub::FastGetPropertyByValue(thread, resultValues.GetTaggedValue(), - resultIndex.GetTaggedValue()); + JSTaggedValue positionTag = FastRuntimeStub::FastGetPropertyByValue(thread, resultValues, resultIndex); JSHandle positionHandle(thread, positionTag); uint32_t position = 0; if (positionHandle->IsInt()) { @@ -965,8 +953,7 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) // j. Let namedCaptures be ? Get(result, "groups"). JSHandle groupsKey = globalConst->GetHandledGroupsString(); - JSTaggedValue named = - FastRuntimeStub::FastGetPropertyByValue(thread, resultValues.GetTaggedValue(), groupsKey.GetTaggedValue()); + JSTaggedValue named = FastRuntimeStub::FastGetPropertyByValue(thread, resultValues, groupsKey); JSHandle namedCaptures(thread, named); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // m. If functionalReplace is true, then @@ -1425,8 +1412,7 @@ JSTaggedValue BuiltinsRegExp::RegExpBuiltinExec(JSThread *thread, const JSHandle const GlobalEnvConstants *globalConst = thread->GlobalConstants(); JSHandle lastIndexHandle = globalConst->GetHandledLastIndexString(); - JSTaggedValue result = - FastRuntimeStub::FastGetPropertyByValue(thread, regexp.GetTaggedValue(), lastIndexHandle.GetTaggedValue()); + JSTaggedValue result = FastRuntimeStub::FastGetPropertyByValue(thread, regexp, lastIndexHandle); int32_t lastIndex = 0; if (result.IsInt()) { lastIndex = result.GetInt(); @@ -1438,14 +1424,10 @@ JSTaggedValue BuiltinsRegExp::RegExpBuiltinExec(JSThread *thread, const JSHandle } JSHandle globalHandle = globalConst->GetHandledGlobalString(); - bool global = - FastRuntimeStub::FastGetPropertyByValue(thread, regexp.GetTaggedValue(), globalHandle.GetTaggedValue()) - .ToBoolean(); + bool global = FastRuntimeStub::FastGetPropertyByValue(thread, regexp, globalHandle).ToBoolean(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); JSHandle stickyHandle = globalConst->GetHandledStickyString(); - bool sticky = - FastRuntimeStub::FastGetPropertyByValue(thread, regexp.GetTaggedValue(), stickyHandle.GetTaggedValue()) - .ToBoolean(); + bool sticky = FastRuntimeStub::FastGetPropertyByValue(thread, regexp, stickyHandle).ToBoolean(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (!global && !sticky) { lastIndex = 0; @@ -1458,8 +1440,8 @@ JSTaggedValue BuiltinsRegExp::RegExpBuiltinExec(JSThread *thread, const JSHandle JSHandle cacheTable(thread->GetEcmaVM()->GetRegExpCache()); uint32_t length = static_cast(inputStr->GetTaggedObject())->GetLength(); if (lastIndex > static_cast(length)) { - FastRuntimeStub::FastSetPropertyByValue(thread, regexp.GetTaggedValue(), lastIndexHandle.GetTaggedValue(), - JSTaggedValue(0)); + FastRuntimeStub::FastSetPropertyByValue(thread, regexp, lastIndexHandle, + thread->GlobalConstants()->GetHandledZero()); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); return JSTaggedValue::Null(); } @@ -1482,8 +1464,8 @@ JSTaggedValue BuiltinsRegExp::RegExpBuiltinExec(JSThread *thread, const JSHandle if (!matchResult.isSuccess_) { if (global || sticky) { JSHandle lastIndexValue(thread, JSTaggedValue(0)); - FastRuntimeStub::FastSetPropertyByValue(thread, regexp.GetTaggedValue(), lastIndexHandle.GetTaggedValue(), - JSTaggedValue(0)); + FastRuntimeStub::FastSetPropertyByValue(thread, regexp, lastIndexHandle, + thread->GlobalConstants()->GetHandledZero()); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } return JSTaggedValue::Null(); @@ -1491,8 +1473,8 @@ JSTaggedValue BuiltinsRegExp::RegExpBuiltinExec(JSThread *thread, const JSHandle uint32_t endIndex = matchResult.endIndex_; if (global || sticky) { // a. Let setStatus be Set(R, "lastIndex", e, true). - FastRuntimeStub::FastSetPropertyByValue(thread, regexp.GetTaggedValue(), lastIndexHandle.GetTaggedValue(), - JSTaggedValue(endIndex)); + JSTaggedValue endIndexVal(endIndex); + FastRuntimeStub::FastSetPropertyByValue(thread, regexp, lastIndexHandle, HandleFromLocal(&endIndexVal)); // b. ReturnIfAbrupt(setStatus). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } @@ -1564,8 +1546,7 @@ JSTaggedValue BuiltinsRegExp::RegExpExec(JSThread *thread, const JSHandleGlobalConstants(); JSHandle execHandle = globalConst->GetHandledExecString(); - JSTaggedValue execVal = - FastRuntimeStub::FastGetPropertyByValue(thread, regexp.GetTaggedValue(), execHandle.GetTaggedValue()); + JSTaggedValue execVal = FastRuntimeStub::FastGetPropertyByValue(thread, regexp, execHandle); JSHandle exec(thread, execVal); // 4. ReturnIfAbrupt(exec). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -1766,8 +1747,7 @@ JSTaggedValue BuiltinsRegExp::RegExpInitialize(JSThread *thread, const JSHandle< } // 14. Let setStatus be Set(obj, "lastIndex", 0, true). JSHandle lastIndexString = thread->GlobalConstants()->GetHandledLastIndexString(); - FastRuntimeStub::FastSetPropertyByValue(thread, obj.GetTaggedValue(), lastIndexString.GetTaggedValue(), - JSTaggedValue(0)); + FastRuntimeStub::FastSetPropertyByValue(thread, obj, lastIndexString, thread->GlobalConstants()->GetHandledZero()); // 15. ReturnIfAbrupt(setStatus). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 16. Return obj. @@ -1868,8 +1848,8 @@ JSTaggedValue RegExpExecResultCache::FindCachedResult(JSThread *thread, const JS } SetHitCount(thread, GetHitCount() + 1); JSHandle lastIndexHandle = thread->GlobalConstants()->GetHandledLastIndexString(); - FastRuntimeStub::FastSetPropertyByValue(thread, regexp.GetTaggedValue(), lastIndexHandle.GetTaggedValue(), - Get(index + LAST_INDEX_INDEX)); + JSTaggedValue lastIndex = Get(index + LAST_INDEX_INDEX); // must be primitive + FastRuntimeStub::FastSetPropertyByValue(thread, regexp, lastIndexHandle, HandleFromLocal(&lastIndex)); return result; } diff --git a/runtime/builtins/builtins_typedarray.cpp b/runtime/builtins/builtins_typedarray.cpp index 7e4835c08..9f4582da9 100644 --- a/runtime/builtins/builtins_typedarray.cpp +++ b/runtime/builtins/builtins_typedarray.cpp @@ -1049,8 +1049,8 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv) JSHandle typedArray(argArray); // 12. Let srcBuffer be the value of typedArray’s [[ViewedArrayBuffer]] internal slot. // 13. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError exception. - JSTaggedValue srcBuffer = JSTypedArray::Cast(*typedArray)->GetViewedArrayBuffer(); - if (BuiltinsArrayBuffer::IsDetachedBuffer(srcBuffer)) { + JSMutableHandle srcBuffer(thread, JSTypedArray::Cast(*typedArray)->GetViewedArrayBuffer()); + if (BuiltinsArrayBuffer::IsDetachedBuffer(srcBuffer.GetTaggedValue())) { THROW_TYPE_ERROR_AND_RETURN(thread, "The ArrayBuffer of typedArray is detached buffer.", JSTaggedValue::Exception()); } @@ -1077,9 +1077,9 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv) // d. Let srcByteIndex be 0. // 25. Else, let srcByteIndex be srcByteOffset. int32_t srcByteIndex; - if (JSTaggedValue::SameValue(srcBuffer, targetBuffer.GetTaggedValue())) { - srcBuffer = - BuiltinsArrayBuffer::CloneArrayBuffer(thread, targetBuffer, srcByteOffset, env->GetArrayBufferFunction()); + if (JSTaggedValue::SameValue(srcBuffer.GetTaggedValue(), targetBuffer.GetTaggedValue())) { + srcBuffer.Update( + BuiltinsArrayBuffer::CloneArrayBuffer(thread, targetBuffer, srcByteOffset, env->GetArrayBufferFunction())); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); srcByteIndex = 0; } else { @@ -1250,8 +1250,8 @@ JSTaggedValue BuiltinsTypedArray::Slice(EcmaRuntimeCallInfo *argv) // iv. Increase targetByteIndex by 1. JSMutableHandle value(thread, JSTaggedValue::Undefined()); for (int32_t targetByteIndex = 0; targetByteIndex < count * elementSize; srcByteIndex++, targetByteIndex++) { - JSTaggedValue taggedData = BuiltinsArrayBuffer::GetValueFromBuffer(thread, srcBuffer.GetTaggedValue(), - srcByteIndex, DataViewType::UINT8, true); + JSTaggedValue taggedData = + BuiltinsArrayBuffer::GetValueFromBuffer(thread, srcBuffer, srcByteIndex, DataViewType::UINT8, true); value.Update(taggedData); BuiltinsArrayBuffer::SetValueInBuffer(thread, targetBuffer, targetByteIndex, DataViewType::UINT8, value, true); diff --git a/runtime/global_env_constants.cpp b/runtime/global_env_constants.cpp index 8e93c2780..2c2101c86 100644 --- a/runtime/global_env_constants.cpp +++ b/runtime/global_env_constants.cpp @@ -193,6 +193,7 @@ void GlobalEnvConstants::InitGlobalConstant(JSThread *thread) ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // SPECIAL INIT SetConstant(ConstantIndex::UNDEFINED_INDEX, JSTaggedValue::Undefined()); + SetConstant(ConstantIndex::ZERO_INDEX, JSTaggedValue(0)); SetConstant(ConstantIndex::NULL_INDEX, JSTaggedValue::Null()); auto vm = thread->GetEcmaVM(); SetConstant(ConstantIndex::EMPTY_STRING_OBJECT_INDEX, JSTaggedValue(EcmaString::CreateEmptyString(vm))); @@ -494,7 +495,7 @@ void GlobalEnvConstants::InitGlobalConstant(JSThread *thread) SetConstant(ConstantIndex::INDEX_INDEX, factory->NewFromCanBeCompressString("index").GetTaggedValue()); SetConstant(ConstantIndex::INPUT_INDEX, factory->NewFromCanBeCompressString("input").GetTaggedValue()); SetConstant(ConstantIndex::UNICODE_INDEX, factory->NewFromCanBeCompressString("unicode").GetTaggedValue()); - SetConstant(ConstantIndex::ZERO_INDEX, factory->NewFromCanBeCompressString("0").GetTaggedValue()); + SetConstant(ConstantIndex::ZERO_STRING_INDEX, factory->NewFromCanBeCompressString("0").GetTaggedValue()); SetConstant(ConstantIndex::VALUES_INDEX, factory->NewFromCanBeCompressString("values").GetTaggedValue()); SetConstant(ConstantIndex::YOUNG_GC, factory->NewFromCanBeCompressString("young").GetTaggedValue()); SetConstant(ConstantIndex::THRESHOLD_GC, factory->NewFromCanBeCompressString("threshold").GetTaggedValue()); diff --git a/runtime/global_env_constants.h b/runtime/global_env_constants.h index 0aba1ff7c..df6b20572 100644 --- a/runtime/global_env_constants.h +++ b/runtime/global_env_constants.h @@ -82,6 +82,7 @@ class JSThread; #define GLOBAL_ENV_CONSTANT_SPECIAL(V) \ V(JSTaggedValue, Undefined, UNDEFINED_INDEX, ecma_roots_special) \ V(JSTaggedValue, Null, NULL_INDEX, ecma_roots_special) \ + V(JSTaggedValue, Zero, ZERO_INDEX, ecma_roots_special) \ V(JSTaggedValue, EmptyString, EMPTY_STRING_OBJECT_INDEX, ecma_roots_special) /* GlobalConstant */ // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) @@ -309,7 +310,7 @@ class JSThread; V(JSTaggedValue, IndexString, INDEX_INDEX, index) \ V(JSTaggedValue, InputString, INPUT_INDEX, input) \ V(JSTaggedValue, UnicodeString, UNICODE_INDEX, unicode) \ - V(JSTaggedValue, ZeroString, ZERO_INDEX, zero) \ + V(JSTaggedValue, ZeroString, ZERO_STRING_INDEX, zero) \ V(JSTaggedValue, FlagsString, FLAGS_INDEX, flags) \ V(JSTaggedValue, BackslashString, BACKSLASH_INDEX, backslash) \ V(JSTaggedValue, GString, G_INDEX, g) \ diff --git a/runtime/ic/ic_runtime_stub-inl.h b/runtime/ic/ic_runtime_stub-inl.h index b5fca2986..2078b4b9d 100644 --- a/runtime/ic/ic_runtime_stub-inl.h +++ b/runtime/ic/ic_runtime_stub-inl.h @@ -346,6 +346,7 @@ void ICRuntimeStub::StoreWithTransition(JSThread *thread, JSObject *receiver, JS int capacity = array->GetLength(); int index = HandlerBase::GetOffset(handler_info); if (index >= capacity) { + [[maybe_unused]] EcmaHandleScope handle_scope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle properties; JSHandle obj_handle(thread, receiver); diff --git a/runtime/interpreter/fast_runtime_stub-inl.h b/runtime/interpreter/fast_runtime_stub-inl.h index ab778f90d..8d3f59f1b 100644 --- a/runtime/interpreter/fast_runtime_stub-inl.h +++ b/runtime/interpreter/fast_runtime_stub-inl.h @@ -358,28 +358,25 @@ JSTaggedValue FastRuntimeStub::GetPropertyByIndex(JSThread *thread, JSTaggedValu } template -JSTaggedValue FastRuntimeStub::GetPropertyByValue(JSThread *thread, JSTaggedValue *receiver, JSTaggedValue *key) +JSTaggedValue FastRuntimeStub::GetPropertyByValue(JSThread *thread, JSHandle receiver, + JSHandle key) { INTERPRETER_TRACE(thread, GetPropertyByValue); if (UNLIKELY(!key->IsNumber() && !key->IsStringOrSymbol())) { return JSTaggedValue::Hole(); } // fast path - auto index = TryToElementsIndex(*key); + auto index = TryToElementsIndex(key.GetTaggedValue()); if (LIKELY(index < JSObject::MAX_ELEMENT_INDEX)) { - return GetPropertyByIndex(thread, *receiver, index); + return GetPropertyByIndex(thread, receiver.GetTaggedValue(), index); } if (!key->IsNumber()) { - if (key->IsString() && !EcmaString::Cast(key->GetTaggedObject())->IsInternString()) { + JSTaggedValue raw_key = key.GetTaggedValue(); + if (raw_key.IsString() && !EcmaString::Cast(raw_key.GetTaggedObject())->IsInternString()) { // update string stable - [[maybe_unused]] EcmaHandleScope handle_scope(thread); - JSHandle receiver_handler(thread, *receiver); - *key = - JSTaggedValue(thread->GetEcmaVM()->GetFactory()->InternString(JSHandle(thread, *key))); - // Maybe moved by GC - *receiver = receiver_handler.GetTaggedValue(); + raw_key = JSTaggedValue(thread->GetEcmaVM()->GetFactory()->InternString(key)); } - return FastRuntimeStub::GetPropertyByName(thread, *receiver, *key); + return FastRuntimeStub::GetPropertyByName(thread, receiver.GetTaggedValue(), raw_key); } return JSTaggedValue::Hole(); } @@ -563,30 +560,26 @@ JSTaggedValue FastRuntimeStub::SetPropertyByIndex(JSThread *thread, JSTaggedValu } template -JSTaggedValue FastRuntimeStub::SetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue value) +JSTaggedValue FastRuntimeStub::SetPropertyByValue(JSThread *thread, JSHandle receiver, + JSHandle key, JSHandle value) { INTERPRETER_TRACE(thread, SetPropertyByValue); - if (UNLIKELY(!key.IsNumber() && !key.IsStringOrSymbol())) { + if (UNLIKELY(!key->IsNumber() && !key->IsStringOrSymbol())) { return JSTaggedValue::Hole(); } // fast path - auto index = TryToElementsIndex(key); + auto index = TryToElementsIndex(key.GetTaggedValue()); if (LIKELY(index < JSObject::MAX_ELEMENT_INDEX)) { - return SetPropertyByIndex(thread, receiver, index, value); + return SetPropertyByIndex(thread, receiver.GetTaggedValue(), index, value.GetTaggedValue()); } - if (!key.IsNumber()) { - if (key.IsString() && !EcmaString::Cast(key.GetTaggedObject())->IsInternString()) { + if (!key->IsNumber()) { + JSTaggedValue raw_key = key.GetTaggedValue(); + if (raw_key.IsString() && !EcmaString::Cast(raw_key.GetTaggedObject())->IsInternString()) { // update string stable - [[maybe_unused]] EcmaHandleScope handle_scope(thread); - JSHandle receiver_handler(thread, receiver); - JSHandle value_handler(thread, value); - key = JSTaggedValue(thread->GetEcmaVM()->GetFactory()->InternString(JSHandle(thread, key))); - // Maybe moved by GC - receiver = receiver_handler.GetTaggedValue(); - value = value_handler.GetTaggedValue(); + raw_key = JSTaggedValue(thread->GetEcmaVM()->GetFactory()->InternString(key)); } - return FastRuntimeStub::SetPropertyByName(thread, receiver, key, value); + return FastRuntimeStub::SetPropertyByName(thread, receiver.GetTaggedValue(), raw_key, + value.GetTaggedValue()); } return JSTaggedValue::Hole(); } @@ -644,72 +637,59 @@ bool FastRuntimeStub::FastSetPropertyByIndex(JSThread *thread, JSTaggedValue rec JSTaggedValue value) { INTERPRETER_TRACE(thread, FastSetPropertyByIndex); + JSTaggedType raw_receiver = receiver.GetRawData(); + JSTaggedType raw_value = value.GetRawData(); + [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); JSTaggedValue result = FastRuntimeStub::SetPropertyByIndex(thread, receiver, index, value); if (!result.IsHole()) { return result != JSTaggedValue::Exception(); } - // CSA reports usage of 'receiver' and 'value' after GC in function FastRuntimeStub::SetPropertyByIndex. - // In case the function throws an exception its result will be JSTaggedValue::Exception() we gets in - // the 'if' condition above and return. - // SUPPRESS_CSA_NEXTLINE(alpha.core.WasteObjHeader) + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); + [[maybe_unused]] EcmaHandleScope handle_scope(thread); + receiver = JSTaggedValue(raw_receiver); + value = JSTaggedValue(raw_value); return JSTaggedValue::SetProperty(thread, JSHandle(thread, receiver), index, - // SUPPRESS_CSA_NEXTLINE(alpha.core.WasteObjHeader) JSHandle(thread, value), true); } -bool FastRuntimeStub::FastSetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue value) +bool FastRuntimeStub::FastSetPropertyByValue(JSThread *thread, JSHandle receiver, + JSHandle key, JSHandle value) { INTERPRETER_TRACE(thread, FastSetPropertyByValue); JSTaggedValue result = FastRuntimeStub::SetPropertyByValue(thread, receiver, key, value); if (!result.IsHole()) { return result != JSTaggedValue::Exception(); } - // CSA reports usage of 'receiver' and 'value' after GC in the function 'SetPropertyByName' called from - // 'SetPropertyByValue'. - // In this case we get in the 'if' condition above and return. - // SUPPRESS_CSA_NEXTLINE(alpha.core.WasteObjHeader) - return JSTaggedValue::SetProperty(thread, JSHandle(thread, receiver), - // SUPPRESS_CSA_NEXTLINE(alpha.core.WasteObjHeader) - JSHandle(thread, key), JSHandle(thread, value), - true); + return JSTaggedValue::SetProperty(thread, receiver, key, value, true); } // must not use for interpreter -JSTaggedValue FastRuntimeStub::FastGetPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key) +JSTaggedValue FastRuntimeStub::FastGetPropertyByName(JSThread *thread, JSHandle receiver, + JSHandle key) { INTERPRETER_TRACE(thread, FastGetPropertyByName); - ASSERT(key.IsStringOrSymbol()); - if (key.IsString() && !EcmaString::Cast(key.GetTaggedObject())->IsInternString()) { - JSHandle receiver_handler(thread, receiver); - key = JSTaggedValue(thread->GetEcmaVM()->GetFactory()->InternString(JSHandle(thread, key))); - // Maybe moved by GC - receiver = receiver_handler.GetTaggedValue(); + ASSERT(key->IsStringOrSymbol()); + JSTaggedValue raw_key = key.GetTaggedValue(); + if (raw_key.IsString() && !EcmaString::Cast(raw_key.GetTaggedObject())->IsInternString()) { + raw_key = JSTaggedValue(thread->GetEcmaVM()->GetFactory()->InternString(key)); } - JSTaggedValue result = FastRuntimeStub::GetPropertyByName(thread, receiver, key); + JSTaggedValue result = FastRuntimeStub::GetPropertyByName(thread, receiver.GetTaggedValue(), raw_key); if (result.IsHole()) { - return JSTaggedValue::GetProperty(thread, JSHandle(thread, receiver), - JSHandle(thread, key)) + [[maybe_unused]] EcmaHandleScope handle_scope(thread); + return JSTaggedValue::GetProperty(thread, receiver, JSHandle(thread, raw_key)) .GetValue() .GetTaggedValue(); } return result; } -JSTaggedValue FastRuntimeStub::FastGetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key) +JSTaggedValue FastRuntimeStub::FastGetPropertyByValue(JSThread *thread, JSHandle receiver, + JSHandle key) { INTERPRETER_TRACE(thread, FastGetPropertyByValue); - JSTaggedValue result = FastRuntimeStub::GetPropertyByValue(thread, &receiver, &key); + JSTaggedValue result = FastRuntimeStub::GetPropertyByValue(thread, receiver, key); if (result.IsHole()) { - // CSA reports usage of 'receiver' and 'key' after GC in the function 'GetPropertyByValue'. - // In case GC is triggered in the function and the objects are moved the function returns - // new addreses of 'receiver' and 'key' via parameters. - // SUPPRESS_CSA_NEXTLINE(alpha.core.WasteObjHeader) - return JSTaggedValue::GetProperty(thread, JSHandle(thread, receiver), - // SUPPRESS_CSA_NEXTLINE(alpha.core.WasteObjHeader) - JSHandle(thread, key)) - .GetValue() - .GetTaggedValue(); + return JSTaggedValue::GetProperty(thread, receiver, key).GetValue().GetTaggedValue(); } return result; } @@ -718,11 +698,13 @@ template // UseHole is only for Array::Sort() which requires Ho JSTaggedValue FastRuntimeStub::FastGetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index) { INTERPRETER_TRACE(thread, FastGetPropertyByIndex); + JSTaggedType raw_receiver = receiver.GetRawData(); + [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); JSTaggedValue result = FastRuntimeStub::GetPropertyByIndex(thread, receiver, index); if (result.IsHole() && !USE_HOLE) { - // CSA reports usage of 'receiver' after GC in the function 'CallGetter' which is called from - // GetPropertyByIndex. In case we reach CallGetter the result canot by JSTaggedValue::Hole(). - // SUPPRESS_CSA_NEXTLINE(alpha.core.WasteObjHeader) + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); + [[maybe_unused]] EcmaHandleScope handle_scope(thread); + receiver = JSTaggedValue(raw_receiver); return JSTaggedValue::GetProperty(thread, JSHandle(thread, receiver), index) .GetValue() .GetTaggedValue(); @@ -1129,60 +1111,58 @@ bool FastRuntimeStub::SetOwnElement(JSThread *thread, JSTaggedValue receiver, ui JSHandle(thread, value), PropertyAttributes::Default()); } -bool FastRuntimeStub::FastSetProperty(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, - bool may_throw) +bool FastRuntimeStub::FastSetProperty(JSThread *thread, JSHandle receiver, JSHandle key, + JSHandle value, bool may_throw) { INTERPRETER_TRACE(thread, FastSetProperty); - if (receiver.IsJSObject() && !receiver.IsTypedArray() && (key.IsStringOrSymbol())) { + if (receiver->IsJSObject() && !receiver->IsTypedArray() && (key->IsStringOrSymbol())) { uint32_t index = 0; - if (UNLIKELY(JSTaggedValue::ToElementIndex(key, &index))) { - if (!FastRuntimeStub::IsSpecialIndexedObjForSet(receiver)) { - return FastRuntimeStub::SetElement(thread, receiver, index, value, true); + if (UNLIKELY(JSTaggedValue::ToElementIndex(key.GetTaggedValue(), &index))) { + if (!FastRuntimeStub::IsSpecialIndexedObjForSet(receiver.GetTaggedValue())) { + return FastRuntimeStub::SetElement(thread, receiver.GetTaggedValue(), index, value.GetTaggedValue(), + true); } - return JSTaggedValue::SetProperty(thread, JSHandle(thread, receiver), - JSHandle(thread, key), - JSHandle(thread, value), may_throw); + return JSTaggedValue::SetProperty(thread, receiver, key, value, may_throw); } - if (key.IsString()) { - key = JSTaggedValue(thread->GetEcmaVM()->GetFactory()->InternString(JSHandle(thread, key))); + JSTaggedValue raw_key = key.GetTaggedValue(); + if (raw_key.IsString()) { + raw_key = JSTaggedValue(thread->GetEcmaVM()->GetFactory()->InternString(key)); } - return FastRuntimeStub::SetPropertyByName(thread, receiver, key, value, may_throw); + return FastRuntimeStub::SetPropertyByName(thread, receiver.GetTaggedValue(), raw_key, value.GetTaggedValue(), + may_throw); } - return JSTaggedValue::SetProperty(thread, JSHandle(thread, receiver), - JSHandle(thread, key), JSHandle(thread, value), - may_throw); + return JSTaggedValue::SetProperty(thread, receiver, key, value, may_throw); } -JSTaggedValue FastRuntimeStub::FastGetProperty(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key) +JSTaggedValue FastRuntimeStub::FastGetProperty(JSThread *thread, JSHandle receiver, + JSHandle key) { INTERPRETER_TRACE(thread, FastGetProperty); JSTaggedValue result; - JSHandle receiver_handle(thread, receiver); - JSHandle key_handle(thread, key); - if (receiver.IsJSObject() && !receiver.IsTypedArray() && (key.IsStringOrSymbol())) { + if (receiver->IsJSObject() && !receiver->IsTypedArray() && (key->IsStringOrSymbol())) { uint32_t index = 0; - if (UNLIKELY(JSTaggedValue::ToElementIndex(key, &index))) { - if (FastRuntimeStub::IsSpecialIndexedObjForSet(receiver)) { + if (UNLIKELY(JSTaggedValue::ToElementIndex(key.GetTaggedValue(), &index))) { + if (FastRuntimeStub::IsSpecialIndexedObjForSet(receiver.GetTaggedValue())) { result = JSTaggedValue::Hole(); } else { - result = FastRuntimeStub::GetElement(receiver, index); + result = FastRuntimeStub::GetElement(receiver.GetTaggedValue(), index); } } else { - if (key.IsString()) { - key = JSTaggedValue( - thread->GetEcmaVM()->GetFactory()->InternString(JSHandle(thread, key))); + JSTaggedValue raw_key = key.GetTaggedValue(); + if (raw_key.IsString()) { + raw_key = JSTaggedValue(thread->GetEcmaVM()->GetFactory()->InternString(key)); } - result = FastRuntimeStub::GetPropertyByName(thread, receiver, key); + result = FastRuntimeStub::GetPropertyByName(thread, receiver.GetTaggedValue(), raw_key); } } if (!result.IsHole()) { if (UNLIKELY(result.IsAccessor())) { - return JSObject::CallGetter(thread, AccessorData::Cast(result.GetHeapObject()), receiver_handle); + return JSObject::CallGetter(thread, AccessorData::Cast(result.GetHeapObject()), receiver); } return result; } - return JSTaggedValue::GetProperty(thread, receiver_handle, key_handle).GetValue().GetTaggedValue(); + return JSTaggedValue::GetProperty(thread, receiver, key).GetValue().GetTaggedValue(); } JSTaggedValue FastRuntimeStub::FindOwnProperty(JSThread *thread, JSObject *obj, TaggedArray *properties, diff --git a/runtime/interpreter/fast_runtime_stub.h b/runtime/interpreter/fast_runtime_stub.h index 4df9f2e7b..7548d54d2 100644 --- a/runtime/interpreter/fast_runtime_stub.h +++ b/runtime/interpreter/fast_runtime_stub.h @@ -54,9 +54,10 @@ public: JSTaggedValue value); // set element that is not accessor and is writable static inline bool SetOwnElement(JSThread *thread, JSTaggedValue receiver, uint32_t index, JSTaggedValue value); - static inline bool FastSetProperty(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, - bool may_throw); - static inline JSTaggedValue FastGetProperty(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key); + static inline bool FastSetProperty(JSThread *thread, JSHandle receiver, JSHandle key, + JSHandle value, bool may_throw); + static inline JSTaggedValue FastGetProperty(JSThread *thread, JSHandle receiver, + JSHandle key); static inline JSTaggedValue FindOwnProperty(JSThread *thread, JSObject *obj, TaggedArray *properties, JSTaggedValue key, PropertyAttributes *attr, uint32_t *index_or_entry); static inline JSTaggedValue FindOwnElement(TaggedArray *elements, uint32_t index, bool is_dict, @@ -72,25 +73,28 @@ public: template static inline JSTaggedValue GetPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key); template - static inline JSTaggedValue GetPropertyByValue(JSThread *thread, JSTaggedValue *receiver, JSTaggedValue *key); + static inline JSTaggedValue GetPropertyByValue(JSThread *thread, JSHandle receiver, + JSHandle key); template static inline JSTaggedValue GetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index); template static inline JSTaggedValue SetPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value); template - static inline JSTaggedValue SetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue value); + static inline JSTaggedValue SetPropertyByValue(JSThread *thread, JSHandle receiver, + JSHandle key, JSHandle value); template static inline JSTaggedValue SetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index, JSTaggedValue value); - static inline bool FastSetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, - JSTaggedValue value); + static inline bool FastSetPropertyByValue(JSThread *thread, JSHandle receiver, + JSHandle key, JSHandle value); static inline bool FastSetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index, JSTaggedValue value); - static inline JSTaggedValue FastGetPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key); - static inline JSTaggedValue FastGetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key); + static inline JSTaggedValue FastGetPropertyByName(JSThread *thread, JSHandle receiver, + JSHandle key); + static inline JSTaggedValue FastGetPropertyByValue(JSThread *thread, JSHandle receiver, + JSHandle key); template static inline JSTaggedValue FastGetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index); static inline PropertyAttributes AddPropertyByName(JSThread *thread, JSHandle obj_handle, diff --git a/runtime/intrinsics-inl.h b/runtime/intrinsics-inl.h index a27b6ec0f..579899d0d 100644 --- a/runtime/intrinsics-inl.h +++ b/runtime/intrinsics-inl.h @@ -420,13 +420,15 @@ INLINE_ECMA_INTRINSICS uint64_t TryLdGlobalByName(JSThread *thread, uint32_t str [[maybe_unused]] uint16_t slot_id) { auto constpool = GetConstantPool(thread); - auto global_obj = GetGlobalObject(thread); - auto prop = constpool->GetObjectFromCache(string_id); + JSTaggedType global_obj = GetGlobalObject(thread).GetRawData(); + JSTaggedType prop = constpool->GetObjectFromCache(string_id).GetRawData(); JSTaggedValue result = JSTaggedValue::Hole(); + [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC if (ICRuntimeStub::HaveICForFunction(thread)) { - result = ICRuntimeStub::LoadGlobalICByName(thread, global_obj, prop, slot_id, true); + result = + ICRuntimeStub::LoadGlobalICByName(thread, JSTaggedValue(global_obj), JSTaggedValue(prop), slot_id, true); if (!result.IsHole()) { return result.GetRawData(); } @@ -434,12 +436,13 @@ INLINE_ECMA_INTRINSICS uint64_t TryLdGlobalByName(JSThread *thread, uint32_t str #endif bool found = false; - - result = FastRuntimeStub::GetGlobalOwnProperty(global_obj, prop, &found); + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); + result = FastRuntimeStub::GetGlobalOwnProperty(JSTaggedValue(global_obj), JSTaggedValue(prop), &found); if (found) { return result.GetRawData(); } - return SlowRuntimeStub::TryLdGlobalByName(thread, global_obj, prop).GetRawData(); + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); + return SlowRuntimeStub::TryLdGlobalByName(thread, JSTaggedValue(global_obj), JSTaggedValue(prop)).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) @@ -904,13 +907,14 @@ INLINE_ECMA_INTRINSICS uint64_t Ldglobal(JSThread *thread) INLINE_ECMA_INTRINSICS uint64_t LdObjByValue(JSThread *thread, uint64_t rec, uint64_t pkey, [[maybe_unused]] uint16_t slot_id) { - auto receiver = JSTaggedValue(rec); - auto prop_key = JSTaggedValue(pkey); - + // If ICRuntimeStub::LoadICByValue triggers GC it mustn't return Hole. + // Using rec and pkey after ICRuntimeStub::LoadICByValue is valid. + // To suppress CSA keep pointers in uint64_t. JSTaggedValue res = JSTaggedValue::Hole(); + [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC if (ICRuntimeStub::HaveICForFunction(thread)) { - res = ICRuntimeStub::LoadICByValue(thread, receiver, prop_key, slot_id); + res = ICRuntimeStub::LoadICByValue(thread, JSTaggedValue(rec), JSTaggedValue(pkey), slot_id); if (LIKELY(!res.IsHole())) { return res.GetRawData(); } @@ -918,218 +922,238 @@ INLINE_ECMA_INTRINSICS uint64_t LdObjByValue(JSThread *thread, uint64_t rec, uin #endif // fast path - if (LIKELY(receiver.IsHeapObject())) { - res = FastRuntimeStub::GetPropertyByValue(thread, &receiver, &prop_key); + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); + [[maybe_unused]] EcmaHandleScope handle_scope(thread); + JSHandle receiver(thread, JSTaggedValue(rec)); + JSHandle prop_key(thread, JSTaggedValue(pkey)); + if (LIKELY(receiver->IsHeapObject())) { + res = FastRuntimeStub::GetPropertyByValue(thread, receiver, prop_key); if (!res.IsHole()) { return res.GetRawData(); } } // slow path - return SlowRuntimeStub::LdObjByValue(thread, receiver, prop_key, false, JSTaggedValue::Undefined()).GetRawData(); + return SlowRuntimeStub::LdObjByValue(thread, receiver.GetTaggedValue(), prop_key.GetTaggedValue(), false, + JSTaggedValue::Undefined()) + .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t StObjByValue(JSThread *thread, uint64_t rec, uint64_t pkey, uint64_t val, [[maybe_unused]] uint16_t slot_id) { - auto receiver = JSTaggedValue(rec); - auto prop_key = JSTaggedValue(pkey); - auto value = JSTaggedValue(val); - + // If ICRuntimeStub::StoreICByValue triggers GC it mustn't return Hole. + // Using rec and pkey after ICRuntimeStub::StoreICByValue is valid. + // To suppress CSA keep pointers in uint64_t. JSTaggedValue res = JSTaggedValue::Hole(); + [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC if (ICRuntimeStub::HaveICForFunction(thread)) { - res = ICRuntimeStub::StoreICByValue(thread, receiver, prop_key, value, slot_id); + res = + ICRuntimeStub::StoreICByValue(thread, JSTaggedValue(rec), JSTaggedValue(pkey), JSTaggedValue(val), slot_id); if (LIKELY(!res.IsHole())) { return res.GetRawData(); } } #endif - { - [[maybe_unused]] EcmaHandleScope handle_scope(thread); - JSHandle receiver_handle(thread, receiver); - JSHandle prop_key_handle(thread, prop_key); - JSHandle value_handle(thread, value); - - if (receiver.IsHeapObject()) { - res = FastRuntimeStub::SetPropertyByValue(thread, receiver, prop_key, value); - if (!res.IsHole()) { - return res.GetRawData(); - } - } - // slow path - receiver = receiver_handle.GetTaggedValue(); // May be moved by GC - prop_key = prop_key_handle.GetTaggedValue(); // May be moved by GC - value = value_handle.GetTaggedValue(); // May be moved by GC + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); + [[maybe_unused]] EcmaHandleScope handle_scope(thread); + JSHandle receiver(thread, JSTaggedValue(rec)); + JSHandle prop_key(thread, JSTaggedValue(pkey)); + JSHandle value(thread, JSTaggedValue(val)); + + if (receiver->IsHeapObject()) { + res = FastRuntimeStub::SetPropertyByValue(thread, receiver, prop_key, value); + if (!res.IsHole()) { + return res.GetRawData(); + } } - return SlowRuntimeStub::StObjByValue(thread, receiver, prop_key, value).GetRawData(); + return SlowRuntimeStub::StObjByValue(thread, receiver.GetTaggedValue(), prop_key.GetTaggedValue(), + value.GetTaggedValue()) + .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t TryStGlobalByName(JSThread *thread, uint32_t string_id, uint64_t value, [[maybe_unused]] uint16_t slot_id) { - JSTaggedValue prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id); - auto global_obj = GetGlobalObject(thread); + JSTaggedType prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id).GetRawData(); + JSTaggedType global_obj = GetGlobalObject(thread).GetRawData(); JSTaggedValue result = JSTaggedValue::Hole(); + [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC if (ICRuntimeStub::HaveICForFunction(thread)) { - result = ICRuntimeStub::StoreGlobalICByName(thread, global_obj, prop_key, JSTaggedValue(value), slot_id, true); + result = ICRuntimeStub::StoreGlobalICByName(thread, JSTaggedValue(global_obj), JSTaggedValue(prop_key), + JSTaggedValue(value), slot_id, true); if (!result.IsHole()) { return result.GetRawData(); } } #endif + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); bool found = false; // 2. find from global object - FastRuntimeStub::GetGlobalOwnProperty(global_obj, prop_key, &found); + FastRuntimeStub::GetGlobalOwnProperty(JSTaggedValue(global_obj), JSTaggedValue(prop_key), &found); if (!found) { - result = SlowRuntimeStub::ThrowReferenceError(thread, prop_key, " is not defined"); - if (result.IsException()) { - return result.GetRawData(); - } + result = SlowRuntimeStub::ThrowReferenceError(thread, JSTaggedValue(prop_key), " is not defined"); + ASSERT(result.IsException()); + return result.GetRawData(); } - return SlowRuntimeStub::StGlobalVar(thread, prop_key, JSTaggedValue(value)).GetRawData(); + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); + return SlowRuntimeStub::StGlobalVar(thread, JSTaggedValue(prop_key), JSTaggedValue(value)).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t LdGlobalVar(JSThread *thread, uint32_t string_id, [[maybe_unused]] uint16_t slot_id) { - auto global_obj = thread->GetGlobalObject(); - auto prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id); + JSTaggedType global_obj = thread->GetGlobalObject().GetRawData(); + JSTaggedType prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id).GetRawData(); JSTaggedValue result = JSTaggedValue::Hole(); + [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC if (ICRuntimeStub::HaveICForFunction(thread)) { - result = ICRuntimeStub::LoadGlobalICByName(thread, global_obj, prop_key, slot_id); + result = ICRuntimeStub::LoadGlobalICByName(thread, JSTaggedValue(global_obj), JSTaggedValue(prop_key), slot_id); if (!result.IsHole()) { return result.GetRawData(); } } #endif + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); bool found = false; - result = FastRuntimeStub::GetGlobalOwnProperty(global_obj, prop_key, &found); + result = FastRuntimeStub::GetGlobalOwnProperty(JSTaggedValue(global_obj), JSTaggedValue(prop_key), &found); if (found) { return result.GetRawData(); } - return SlowRuntimeStub::LdGlobalVar(thread, global_obj, prop_key).GetRawData(); + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); + return SlowRuntimeStub::LdGlobalVar(thread, JSTaggedValue(global_obj), JSTaggedValue(prop_key)).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t StGlobalVar(JSThread *thread, uint32_t string_id, uint64_t value, [[maybe_unused]] uint16_t slot_id) { - auto global_obj = thread->GetGlobalObject(); - JSTaggedValue prop = GetConstantPool(thread)->GetObjectFromCache(string_id); + JSTaggedType global_obj = thread->GetGlobalObject().GetRawData(); + JSTaggedType prop = GetConstantPool(thread)->GetObjectFromCache(string_id).GetRawData(); + [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC if (ICRuntimeStub::HaveICForFunction(thread)) { - JSTaggedValue result = - ICRuntimeStub::StoreGlobalICByName(thread, global_obj, prop, JSTaggedValue(value), slot_id); + JSTaggedValue result = ICRuntimeStub::StoreGlobalICByName(thread, JSTaggedValue(global_obj), + JSTaggedValue(prop), JSTaggedValue(value), slot_id); if (!result.IsHole()) { return result.GetRawData(); } } #endif - return SlowRuntimeStub::StGlobalVar(thread, prop, JSTaggedValue(value)).GetRawData(); + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); + return SlowRuntimeStub::StGlobalVar(thread, JSTaggedValue(prop), JSTaggedValue(value)).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t LdObjByName(JSThread *thread, uint32_t string_id, uint64_t object, [[maybe_unused]] uint16_t slot_id) { - auto obj = JSTaggedValue(object); - auto prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id); - + // CSA reports usage object and prop_key after GC triggered in ICRuntimeStub::LoadICByName. + // If ICRuntimeStub::LoadICByName triggers GC it mustn't return Hole. + // Using object and prop_key after ICRuntimeStub::LoadICByName is valid. + // To suppress CSA keep pointers in uint64_t and JSTaggedType. + JSTaggedType prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id).GetRawData(); JSTaggedValue res = JSTaggedValue::Hole(); + [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC if (ICRuntimeStub::HaveICForFunction(thread)) { - res = ICRuntimeStub::LoadICByName(thread, obj, prop_key, slot_id); + res = ICRuntimeStub::LoadICByName(thread, JSTaggedValue(object), JSTaggedValue(prop_key), slot_id); if (LIKELY(!res.IsHole())) { return res.GetRawData(); } } #endif - if (LIKELY(obj.IsHeapObject())) { - res = FastRuntimeStub::GetPropertyByName(thread, obj, prop_key); + if (LIKELY(JSTaggedValue(object).IsHeapObject())) { + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); + res = FastRuntimeStub::GetPropertyByName(thread, JSTaggedValue(object), JSTaggedValue(prop_key)); if (!res.IsHole()) { return res.GetRawData(); } } - return SlowRuntimeStub::LdObjByName(thread, obj, prop_key, false, JSTaggedValue::Undefined()).GetRawData(); + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); + return SlowRuntimeStub::LdObjByName(thread, JSTaggedValue(object), JSTaggedValue(prop_key), false, + JSTaggedValue::Undefined()) + .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t StObjByName(JSThread *thread, uint32_t string_id, uint64_t object, uint64_t val, [[maybe_unused]] uint16_t slot_id) { - [[maybe_unused]] EcmaHandleScope handle_scope(thread); - - auto obj = JSTaggedValue(object); - auto value = JSTaggedValue(val); - - auto prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id); - + // CSA reports usage object, prop_key and val after GC triggered in ICRuntimeStub::StoreICByName. + // If ICRuntimeStub::StoreICByName triggers GC it mustn't return Hole. + // Using object, prop_key and val after ICRuntimeStub::StoreICByName is valid. + // To suppress CSA keep pointers in uint64_t and JSTaggedType. + JSTaggedType prop_key = GetConstantPool(thread)->GetObjectFromCache(string_id).GetRawData(); JSTaggedValue res = JSTaggedValue::Hole(); + [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); #if ECMASCRIPT_ENABLE_IC if (ICRuntimeStub::HaveICForFunction(thread)) { - res = ICRuntimeStub::StoreICByName(thread, obj, prop_key, value, slot_id); + res = ICRuntimeStub::StoreICByName(thread, JSTaggedValue(object), JSTaggedValue(prop_key), JSTaggedValue(val), + slot_id); if (LIKELY(!res.IsHole())) { return res.GetRawData(); } } #endif - if (obj.IsHeapObject()) { - res = FastRuntimeStub::SetPropertyByName(thread, obj, prop_key, value); + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); + if (JSTaggedValue(object).IsHeapObject()) { + res = FastRuntimeStub::SetPropertyByName(thread, JSTaggedValue(object), JSTaggedValue(prop_key), + JSTaggedValue(val)); if (!res.IsHole()) { return res.GetRawData(); } } - return SlowRuntimeStub::StObjByName(thread, obj, prop_key, value).GetRawData(); + return SlowRuntimeStub::StObjByName(thread, JSTaggedValue(object), JSTaggedValue(prop_key), JSTaggedValue(val)) + .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t LdObjByIndex(JSThread *thread, uint32_t idx, uint64_t uobj) { - auto obj = JSTaggedValue(uobj); - // fast path - if (LIKELY(obj.IsHeapObject())) { - JSTaggedValue res = FastRuntimeStub::GetPropertyByIndex(thread, obj, idx); + [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); + if (LIKELY(JSTaggedValue(uobj).IsHeapObject())) { + JSTaggedValue res = FastRuntimeStub::GetPropertyByIndex(thread, JSTaggedValue(uobj), idx); if (!res.IsHole()) { return res.GetRawData(); } } + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); // not meet fast condition or fast path return hole, walk slow path // slow stub not need receiver - return SlowRuntimeStub::LdObjByIndex(thread, obj, idx, false, JSTaggedValue::Undefined()).GetRawData(); + return SlowRuntimeStub::LdObjByIndex(thread, JSTaggedValue(uobj), idx, false, JSTaggedValue::Undefined()) + .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t StObjByIndex(JSThread *thread, uint32_t idx, uint64_t uobj, uint64_t uval) { - [[maybe_unused]] EcmaHandleScope handle_scope(thread); - - auto obj = JSTaggedValue(uobj); - auto val = JSTaggedValue(uval); - // fast path - if (obj.IsHeapObject()) { - JSTaggedValue res = FastRuntimeStub::SetPropertyByIndex(thread, obj, idx, val); + [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); + if (JSTaggedValue(uobj).IsHeapObject()) { + JSTaggedValue res = FastRuntimeStub::SetPropertyByIndex(thread, JSTaggedValue(uobj), idx, JSTaggedValue(uval)); if (!res.IsHole()) { return res.GetRawData(); } } + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); // slow path - return SlowRuntimeStub::StObjByIndex(thread, obj, idx, val).GetRawData(); + return SlowRuntimeStub::StObjByIndex(thread, JSTaggedValue(uobj), idx, JSTaggedValue(uval)).GetRawData(); } template bigintOP(JSThread *, JSHandle, JSHandle), bool is_u_left = false, @@ -1783,77 +1807,60 @@ INLINE_ECMA_INTRINSICS uint64_t CreateRegExpWithLiteral(JSThread *thread, uint32 // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t StOwnByIndex(JSThread *thread, uint64_t object, uint64_t idx, uint64_t val) { - auto obj = JSTaggedValue(object); - auto value = JSTaggedValue(val); - - { - [[maybe_unused]] EcmaHandleScope handle_scope(thread); - JSHandle obj_handle(thread, JSTaggedValue(object)); - JSHandle value_handle(thread, JSTaggedValue(val)); - - if (obj.IsHeapObject() && !obj.IsClassConstructor() && !obj.IsClassPrototype()) { - JSTaggedValue res = FastRuntimeStub::SetPropertyByIndex(thread, obj, idx, value); - if (!res.IsHole()) { - return res.GetRawData(); - } + [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); + if (JSTaggedValue(object).IsHeapObject() && !JSTaggedValue(object).IsClassConstructor() && + !JSTaggedValue(object).IsClassPrototype()) { + JSTaggedValue res = + FastRuntimeStub::SetPropertyByIndex(thread, JSTaggedValue(object), idx, JSTaggedValue(val)); + if (!res.IsHole()) { + return res.GetRawData(); } - - obj = obj_handle.GetTaggedValue(); // Maybe moved by GC - value = value_handle.GetTaggedValue(); // Maybe moved by GC } - return SlowRuntimeStub::StOwnByIndex(thread, obj, idx, value).GetRawData(); + + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); + return SlowRuntimeStub::StOwnByIndex(thread, JSTaggedValue(object), idx, JSTaggedValue(val)).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t StOwnByName(JSThread *thread, uint32_t string_id, uint64_t object, uint64_t val) { - auto obj = JSTaggedValue(object); - auto value = JSTaggedValue(val); - JSTaggedValue prop = GetConstantPool(thread)->GetObjectFromCache(string_id); - - { - [[maybe_unused]] EcmaHandleScope handle_scope(thread); - JSHandle obj_handle(thread, JSTaggedValue(object)); - JSHandle value_handle(thread, JSTaggedValue(val)); + JSTaggedType prop = GetConstantPool(thread)->GetObjectFromCache(string_id).GetRawData(); - if (obj.IsJSObject() && !obj.IsClassConstructor() && !obj.IsClassPrototype()) { - JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, obj, prop, value); - if (!res.IsHole()) { - return res.GetRawData(); - } + [[maybe_unused]] size_t gc = thread->GetEcmaVM()->GetGC()->GetCounter(); + if (JSTaggedValue(object).IsJSObject() && !JSTaggedValue(object).IsClassConstructor() && + !JSTaggedValue(object).IsClassPrototype()) { + JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, JSTaggedValue(object), JSTaggedValue(prop), + JSTaggedValue(val)); + if (!res.IsHole()) { + return res.GetRawData(); } - - obj = obj_handle.GetTaggedValue(); // Maybe moved by GC - value = value_handle.GetTaggedValue(); // Maybe moved by GC - prop = GetConstantPool(thread)->GetObjectFromCache(string_id); // Maybe moved by GC } - return SlowRuntimeStub::StOwnByName(thread, obj, prop, value).GetRawData(); + ASSERT_PRINT(gc == thread->GetEcmaVM()->GetGC()->GetCounter(), "GC happend where it is not supposed"); + + return SlowRuntimeStub::StOwnByName(thread, JSTaggedValue(object), JSTaggedValue(prop), JSTaggedValue(val)) + .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t StOwnByValue(JSThread *thread, uint64_t rec, uint64_t pkey, uint64_t val) { - auto receiver = JSTaggedValue(rec); - auto prop_key = JSTaggedValue(pkey); - auto value = JSTaggedValue(val); - [[maybe_unused]] EcmaHandleScope handle_scope(thread); - JSHandle receiver_handle(thread, receiver); - JSHandle prop_handle(thread, prop_key); - JSHandle value_handle(thread, value); - - if (receiver.IsHeapObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) { - JSTaggedValue res = FastRuntimeStub::SetPropertyByValue(thread, receiver, prop_key, value); - prop_key = prop_handle.GetTaggedValue(); // Maybe moved by GC - value = value_handle.GetTaggedValue(); // Maybe moved by GC + + JSHandle receiver(thread, JSTaggedValue(rec)); + JSHandle prop(thread, JSTaggedValue(pkey)); + JSHandle value(thread, JSTaggedValue(val)); + + if (receiver->IsHeapObject() && !receiver->IsClassConstructor() && !receiver->IsClassPrototype()) { + JSTaggedValue res = FastRuntimeStub::SetPropertyByValue(thread, receiver, prop, value); if (!res.IsHole()) { - if (value.IsJSFunction()) { - JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetHeapObject()), prop_key); + if (value->IsJSFunction()) { + JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetTaggedValue().GetHeapObject()), + prop.GetTaggedValue()); } return res.GetRawData(); } } - return SlowRuntimeStub::StOwnByValue(thread, receiver_handle, prop_handle, value_handle).GetRawData(); + return SlowRuntimeStub::StOwnByValue(thread, receiver, prop, value).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) diff --git a/runtime/js_array.cpp b/runtime/js_array.cpp index 0cc0f2b1d..dec996492 100644 --- a/runtime/js_array.cpp +++ b/runtime/js_array.cpp @@ -362,7 +362,7 @@ JSHandle JSArray::FastGetPropertyByValue(JSThread *thread, const JSHandle JSArray::FastGetPropertyByValue(JSThread *thread, const JSHandle &obj, const JSHandle &key) { - auto result = FastRuntimeStub::FastGetPropertyByValue(thread, obj.GetTaggedValue(), key.GetTaggedValue()); + auto result = FastRuntimeStub::FastGetPropertyByValue(thread, obj, key); return JSHandle(thread, result); } @@ -375,7 +375,6 @@ bool JSArray::FastSetPropertyByValue(JSThread *thread, const JSHandle &obj, const JSHandle &key, const JSHandle &value) { - return FastRuntimeStub::FastSetPropertyByValue(thread, obj.GetTaggedValue(), key.GetTaggedValue(), - value.GetTaggedValue()); + return FastRuntimeStub::FastSetPropertyByValue(thread, obj, key, value); } } // namespace panda::ecmascript diff --git a/runtime/js_handle.h b/runtime/js_handle.h index b3096cb08..9a42105bd 100644 --- a/runtime/js_handle.h +++ b/runtime/js_handle.h @@ -138,6 +138,16 @@ private: friend class GlobalHandleCollection; }; +/** + * A function for wrapping a local primitive TaggedValue into JSHAndle. + */ +inline JSHandle HandleFromLocal(const JSTaggedValue *value) +{ + ASSERT(value->IsNumber() || value->IsBoolean() || value->IsException() || value->IsUndefined() || value->IsNull() || + value->IsHole()); + return JSHandle(ToUintPtr(value)); +} + template <> inline JSTaggedValue *JSHandle::operator->() const { diff --git a/runtime/js_object.cpp b/runtime/js_object.cpp index 149f967e3..d7acfea14 100644 --- a/runtime/js_object.cpp +++ b/runtime/js_object.cpp @@ -1112,8 +1112,7 @@ bool JSObject::CreateDataProperty(JSThread *thread, const JSHandle &ob { ASSERT_PRINT(obj->IsECMAObject(), "Obj is not a valid object"); ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key"); - auto result = FastRuntimeStub::SetPropertyByValue(thread, obj.GetTaggedValue(), key.GetTaggedValue(), - value.GetTaggedValue()); + auto result = FastRuntimeStub::SetPropertyByValue(thread, JSHandle(obj), key, value); if (!result.IsHole()) { return result != JSTaggedValue::Exception(); } @@ -1174,7 +1173,7 @@ bool JSObject::CreateMethodProperty(JSThread *thread, const JSHandle & JSHandle JSObject::GetMethod(JSThread *thread, const JSHandle &obj, const JSHandle &key) { - JSTaggedValue func = FastRuntimeStub::FastGetProperty(thread, obj.GetTaggedValue(), key.GetTaggedValue()); + JSTaggedValue func = FastRuntimeStub::FastGetProperty(thread, obj, key); if (func.IsUndefined() || func.IsNull()) { return JSHandle(thread, JSTaggedValue::Undefined()); } diff --git a/runtime/js_regexp_iterator.cpp b/runtime/js_regexp_iterator.cpp index 192741d5a..c7a23ff5e 100644 --- a/runtime/js_regexp_iterator.cpp +++ b/runtime/js_regexp_iterator.cpp @@ -87,9 +87,8 @@ JSTaggedValue JSRegExpIterator::Next(EcmaRuntimeCallInfo *argv) JSObject::GetProperty(thread, regexHandle, lastIndexString).GetValue()); JSTaggedNumber thisIndex = JSTaggedValue::ToLength(thread, getLastIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - uint32_t nextIndex = BuiltinsRegExp::AdvanceStringIndex(inputStr, thisIndex.ToUint32(), fullUnicode); - FastRuntimeStub::FastSetPropertyByValue(thread, regexHandle.GetTaggedValue(), - lastIndexString.GetTaggedValue(), JSTaggedValue(nextIndex)); + JSTaggedValue nextIndex(BuiltinsRegExp::AdvanceStringIndex(inputStr, thisIndex.ToUint32(), fullUnicode)); + FastRuntimeStub::FastSetPropertyByValue(thread, regexHandle, lastIndexString, HandleFromLocal(&nextIndex)); } // iii. Return ! CreateIterResultObject(match, false). return JSIterator::CreateIterResultObject(thread, matchHandle, false).GetTaggedValue(); diff --git a/runtime/js_typed_array.cpp b/runtime/js_typed_array.cpp index 8029c578f..b93fca2a1 100644 --- a/runtime/js_typed_array.cpp +++ b/runtime/js_typed_array.cpp @@ -100,12 +100,11 @@ bool JSTypedArray::HasProperty(JSThread *thread, const JSHandle & JSTaggedNumber numericIndexNumber = JSTaggedValue::ToNumber(thread, numericIndexHandle); double tNegZero = -0.0; auto eZero = JSTaggedNumber(tNegZero); - JSHandle zero(thread, JSTaggedValue(0)); if (JSTaggedNumber::SameValue(numericIndexNumber, eZero)) { return false; } - if (JSTaggedValue::Less(thread, numericIndexHandle, zero)) { + if (JSTaggedValue::Less(thread, numericIndexHandle, thread->GlobalConstants()->GetHandledZero())) { return false; } int32_t arrLen = TypedArrayHelper::GetArrayLength(thread, typedarrayObj); @@ -162,11 +161,10 @@ bool JSTypedArray::DefineOwnProperty(JSThread *thread, const JSHandle zero(thread, JSTaggedValue(0)); if (JSTaggedNumber::SameValue(numericIndexNumber, eZero)) { return false; } - if (JSTaggedValue::Less(thread, numericIndexHandle, zero)) { + if (JSTaggedValue::Less(thread, numericIndexHandle, thread->GlobalConstants()->GetHandledZero())) { return false; } int32_t arrLen = TypedArrayHelper::GetArrayLength(thread, typedarrayObj); @@ -335,13 +333,13 @@ OperationResult JSTypedArray::IntegerIndexedElementGet(JSThread *thread, const J JSTaggedNumber indexNumber = JSTaggedValue::ToNumber(thread, indexHandle); double tNegZero = -0.0; auto eZero = JSTaggedNumber(tNegZero); - JSHandle zero(thread, JSTaggedValue(0)); if (JSTaggedNumber::SameValue(indexNumber, eZero)) { return OperationResult(thread, JSTaggedValue::Undefined(), PropertyMetaData(true)); } int32_t arrLen = TypedArrayHelper::GetArrayLength(thread, typedarrayObj); JSHandle arrLenHandle(thread, JSTaggedValue(arrLen)); - if (JSTaggedValue::Less(thread, indexHandle, zero) || !JSTaggedValue::Less(thread, indexHandle, arrLenHandle)) { + if (JSTaggedValue::Less(thread, indexHandle, thread->GlobalConstants()->GetHandledZero()) || + !JSTaggedValue::Less(thread, indexHandle, arrLenHandle)) { return OperationResult(thread, JSTaggedValue::Undefined(), PropertyMetaData(true)); } // 9. Let offset be the value of O’s [[ByteOffset]] internal slot. @@ -360,7 +358,7 @@ OperationResult JSTypedArray::IntegerIndexedElementGet(JSThread *thread, const J { // We use buffer without handle and GC can move it. So we have to get buffer each time. // To make developer get buffer each time use scope and don't populate buffer into function's scope. - JSTaggedValue buffer = JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer(); + JSHandle buffer(thread, JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer()); result = BuiltinsArrayBuffer::GetValueFromBuffer(thread, buffer, byteIndex, elementType, true); } return OperationResult(thread, result, PropertyMetaData(true)); @@ -370,14 +368,15 @@ OperationResult JSTypedArray::IntegerIndexedElementGet(JSThread *thread, const J bool JSTypedArray::FastCopyElementToArray(JSThread *thread, const JSHandle &typed_array, JSHandle &array) { + [[maybe_unused]] EcmaHandleScope handle_scope(thread); // 2. Assert: O is an Object that has [[ViewedArrayBuffer]], [[ArrayLength]], [[ByteOffset]], and // [[TypedArrayName]] internal slots. ASSERT(typed_array->IsTypedArray()); // 3. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. JSHandle typedarrayObj(typed_array); - JSTaggedValue buffer = JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer(); + JSHandle buffer(thread, JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer()); // 4. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. - if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { + if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer.GetTaggedValue())) { THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", false); } @@ -442,7 +441,7 @@ OperationResult JSTypedArray::FastElementGet(JSThread *thread, const JSHandleGetViewedArrayBuffer(); + JSHandle buffer(thread, JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer()); JSTaggedValue result = BuiltinsArrayBuffer::GetValueFromBuffer(thread, buffer, byteIndex, elementType, true); return OperationResult(thread, result, PropertyMetaData(true)); } @@ -491,13 +490,13 @@ bool JSTypedArray::IntegerIndexedElementSet(JSThread *thread, const JSHandle zero(thread, JSTaggedValue(0)); if (JSTaggedNumber::SameValue(indexNumber, eZero)) { return false; } int32_t arrLen = TypedArrayHelper::GetArrayLength(thread, typedarrayObj); JSHandle arrLenHandle(thread, JSTaggedValue(arrLen)); - if (JSTaggedValue::Less(thread, indexHandle, zero) || !JSTaggedValue::Less(thread, indexHandle, arrLenHandle)) { + if (JSTaggedValue::Less(thread, indexHandle, thread->GlobalConstants()->GetHandledZero()) || + !JSTaggedValue::Less(thread, indexHandle, arrLenHandle)) { return false; } -- Gitee