add onheap testcase

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I8XTLL
Signed-off-by: linxiang8 <linxiang8@huawei.com>
Change-Id: I62fa6347a641f0de7d45c1c50392bc21c3092a41
This commit is contained in:
linxiang8 2024-01-21 23:31:42 +08:00
parent 02de93935e
commit 4604a5d086
9 changed files with 161 additions and 65 deletions

View File

@ -2299,6 +2299,8 @@ void Builtins::LazyInitialize##Type(const JSHandle<GlobalEnv> &env) const
SetLazyAccessor(globalObject, key, accessor); \
env->Set##Type##Function(thread_, accessor); \
env->Set##Type##FunctionPrototype(thread_, accessor); \
env->Set##Type##RootHclass(thread_, accessor); \
env->Set##Type##RootHclassOnHeap(thread_, accessor); \
}
BUILTIN_TYPED_ARRAY_TYPES(BUILTIN_TYPED_ARRAY_DEFINE_LAZY_INITIALIZE)

View File

@ -355,6 +355,16 @@ JSTaggedValue BuiltinsArkTools::IsAOTCompiled(EcmaRuntimeCallInfo *info)
return JSTaggedValue(method->IsAotWithCallField());
}
JSTaggedValue BuiltinsArkTools::IsOnHeap(EcmaRuntimeCallInfo *info)
{
ASSERT(info);
JSThread *thread = info->GetThread();
[[maybe_unused]] EcmaHandleScope handleScope(thread);
JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
return JSTaggedValue(obj.GetTaggedValue().GetTaggedObject()->GetClass()->IsOnHeapFromBitField());
}
// It is used to check whether a function is aot compiled and deopted at runtime.
JSTaggedValue BuiltinsArkTools::IsAOTDeoptimized(EcmaRuntimeCallInfo *info)
{

View File

@ -46,7 +46,8 @@
V("getElementsKind", GetElementsKind, 1, INVALID) \
V("isAOTCompiled", IsAOTCompiled, 1, INVALID) \
V("isAOTDeoptimized", IsAOTDeoptimized, 1, INVALID) \
V("printLoopHoistProfilerAndReset", PrintLoopHoistProfilerAndReset, 0, INVALID)
V("printLoopHoistProfilerAndReset", PrintLoopHoistProfilerAndReset, 0, INVALID) \
V("isOnHeap", IsOnHeap, 1, INVALID) \
#define BUILTIN_ARK_TOOLS_FUNCTIONS_REGRESS(V) \
V("prepareFunctionForOptimization", PrepareFunctionForOptimization, 1, INVALID) \
@ -183,6 +184,9 @@ public:
// ArkTools.isAOTCompiledAssert(func)
static JSTaggedValue IsAOTDeoptimized(EcmaRuntimeCallInfo *info);
// ArkTools.isOnHeap(object)
static JSTaggedValue IsOnHeap(EcmaRuntimeCallInfo *info);
// ArkTools.GetElementsKind(array)
static JSTaggedValue GetElementsKind(EcmaRuntimeCallInfo *info);

View File

@ -304,42 +304,54 @@ void TypedHCRLowering::LowerStableArrayCheck(GateRef gate)
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
}
void TypedHCRLowering::SetDeoptTypeInfo(BuiltinTypeId id, DeoptType &type, size_t &funcIndex)
void TypedHCRLowering::SetDeoptTypeInfo(BuiltinTypeId id, DeoptType &type, size_t &typedArrayRootHclassIndex,
size_t &typedArrayRootHclassOnHeapIndex)
{
type = DeoptType::NOTARRAY1;
switch (id) {
case BuiltinTypeId::INT8_ARRAY:
funcIndex = GlobalEnv::INT8_ARRAY_FUNCTION_INDEX;
typedArrayRootHclassIndex = GlobalEnv::INT8_ARRAY_ROOT_HCLASS_INDEX;
typedArrayRootHclassOnHeapIndex = GlobalEnv::INT8_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
break;
case BuiltinTypeId::UINT8_ARRAY:
funcIndex = GlobalEnv::UINT8_ARRAY_FUNCTION_INDEX;
typedArrayRootHclassIndex = GlobalEnv::UINT8_ARRAY_ROOT_HCLASS_INDEX;
typedArrayRootHclassOnHeapIndex = GlobalEnv::UINT8_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
break;
case BuiltinTypeId::UINT8_CLAMPED_ARRAY:
funcIndex = GlobalEnv::UINT8_CLAMPED_ARRAY_FUNCTION_INDEX;
typedArrayRootHclassIndex = GlobalEnv::UINT8_CLAMPED_ARRAY_ROOT_HCLASS_INDEX;
typedArrayRootHclassOnHeapIndex = GlobalEnv::UINT8_CLAMPED_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
break;
case BuiltinTypeId::INT16_ARRAY:
funcIndex = GlobalEnv::INT16_ARRAY_FUNCTION_INDEX;
typedArrayRootHclassIndex = GlobalEnv::INT16_ARRAY_ROOT_HCLASS_INDEX;
typedArrayRootHclassOnHeapIndex = GlobalEnv::INT16_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
break;
case BuiltinTypeId::UINT16_ARRAY:
funcIndex = GlobalEnv::UINT16_ARRAY_FUNCTION_INDEX;
typedArrayRootHclassIndex = GlobalEnv::UINT16_ARRAY_ROOT_HCLASS_INDEX;
typedArrayRootHclassOnHeapIndex = GlobalEnv::UINT16_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
break;
case BuiltinTypeId::INT32_ARRAY:
funcIndex = GlobalEnv::INT32_ARRAY_FUNCTION_INDEX;
typedArrayRootHclassIndex = GlobalEnv::INT32_ARRAY_ROOT_HCLASS_INDEX;
typedArrayRootHclassOnHeapIndex = GlobalEnv::INT32_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
break;
case BuiltinTypeId::UINT32_ARRAY:
funcIndex = GlobalEnv::UINT32_ARRAY_FUNCTION_INDEX;
typedArrayRootHclassIndex = GlobalEnv::UINT32_ARRAY_ROOT_HCLASS_INDEX;
typedArrayRootHclassOnHeapIndex = GlobalEnv::UINT32_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
break;
case BuiltinTypeId::FLOAT32_ARRAY:
funcIndex = GlobalEnv::FLOAT32_ARRAY_FUNCTION_INDEX;
typedArrayRootHclassIndex = GlobalEnv::FLOAT32_ARRAY_ROOT_HCLASS_INDEX;
typedArrayRootHclassOnHeapIndex = GlobalEnv::FLOAT32_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
break;
case BuiltinTypeId::FLOAT64_ARRAY:
funcIndex = GlobalEnv::FLOAT64_ARRAY_FUNCTION_INDEX;
typedArrayRootHclassIndex = GlobalEnv::FLOAT64_ARRAY_ROOT_HCLASS_INDEX;
typedArrayRootHclassOnHeapIndex = GlobalEnv::FLOAT64_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
break;
case BuiltinTypeId::BIGINT64_ARRAY:
funcIndex = GlobalEnv::BIGINT64_ARRAY_FUNCTION_INDEX;
typedArrayRootHclassIndex = GlobalEnv::BIGINT64_ARRAY_ROOT_HCLASS_INDEX;
typedArrayRootHclassOnHeapIndex = GlobalEnv::BIGINT64_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
break;
case BuiltinTypeId::BIGUINT64_ARRAY:
funcIndex = GlobalEnv::BIGUINT64_ARRAY_FUNCTION_INDEX;
typedArrayRootHclassIndex = GlobalEnv::BIGUINT64_ARRAY_ROOT_HCLASS_INDEX;
typedArrayRootHclassOnHeapIndex = GlobalEnv::BIGUINT64_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
break;
default:
LOG_ECMA(FATAL) << "this branch is unreachable";
@ -351,24 +363,27 @@ void TypedHCRLowering::LowerTypedArrayCheck(GateRef gate)
{
Environment env(gate, circuit_, &builder_);
TypedArrayMetaDateAccessor accessor = acc_.GetTypedArrayMetaDateAccessor(gate);
size_t typedArrayFuncIndex = GlobalEnv::TYPED_ARRAY_FUNCTION_INDEX;
size_t typedArrayRootHclassIndex = GlobalEnv::INT8_ARRAY_ROOT_HCLASS_INDEX;
size_t typedArrayRootHclassOnHeapIndex = GlobalEnv::INT8_ARRAY_ROOT_HCLASS_ON_HEAP_INDEX;
auto deoptType = DeoptType::NOTCHECK;
auto builtinTypeId = tsManager_->GetTypedArrayBuiltinId(accessor.GetType());
SetDeoptTypeInfo(builtinTypeId, deoptType, typedArrayFuncIndex);
SetDeoptTypeInfo(builtinTypeId, deoptType, typedArrayRootHclassIndex, typedArrayRootHclassOnHeapIndex);
GateRef frameState = GetFrameState(gate);
GateRef glueGlobalEnv = builder_.GetGlobalEnv();
GateRef receiver = acc_.GetValueIn(gate, 0);
GateRef receiverHClass = builder_.LoadHClass(receiver);
GateRef protoOrHclass = builder_.GetGlobalEnvObjHClass(glueGlobalEnv, typedArrayFuncIndex);
GateRef check = builder_.Equal(receiverHClass, protoOrHclass);
builder_.DeoptCheck(check, frameState, deoptType);
GateRef rootHclass = builder_.GetGlobalEnvObj(glueGlobalEnv, typedArrayRootHclassIndex);
GateRef rootOnHeapHclass = builder_.GetGlobalEnvObj(glueGlobalEnv, typedArrayRootHclassOnHeapIndex);
GateRef check1 = builder_.Equal(receiverHClass, rootHclass);
GateRef check2 = builder_.Equal(receiverHClass, rootOnHeapHclass);
builder_.DeoptCheck(builder_.BoolOr(check1, check2), frameState, deoptType);
OnHeapMode onHeapMode = accessor.GetOnHeapMode();
if (accessor.IsAccessElement() && !OnHeap::IsNone(onHeapMode)) {
GateRef profilingOnHeap = builder_.Boolean(OnHeap::ToBoolean(onHeapMode));
GateRef runtimeOnHeap = builder_.IsOnHeap(builder_.LoadHClass(receiver));
GateRef runtimeOnHeap = builder_.IsOnHeap(receiverHClass);
GateRef onHeapCheck = builder_.Equal(profilingOnHeap, runtimeOnHeap);
builder_.DeoptCheck(onHeapCheck, frameState, DeoptType::INCONSISTENTONHEAP1);
}
@ -1022,7 +1037,7 @@ void TypedHCRLowering::LowerTypedArrayLoadElement(GateRef gate, BuiltinTypeId id
result = BuildNotOnHeapTypedArrayLoadElement(receiver, offset, type);
break;
}
case OnHeapMode::NONE: {
default: {
Label isByteArray(&builder_);
Label isArrayBuffer(&builder_);
Label exit(&builder_);
@ -1213,7 +1228,7 @@ void TypedHCRLowering::LowerTypedArrayStoreElement(GateRef gate, BuiltinTypeId i
BuildNotOnHeapTypedArrayStoreElement(receiver, offset, value);
break;
}
case OnHeapMode::NONE: {
default: {
Label isByteArray(&builder_);
Label isArrayBuffer(&builder_);
Label exit(&builder_);

View File

@ -194,7 +194,8 @@ private:
void LowerTypedSuperAllocateThis(GateRef gate, GateRef glue);
void LowerGetSuperConstructor(GateRef gate);
void LowerJSInlineTargetTypeCheck(GateRef gate);
void SetDeoptTypeInfo(BuiltinTypeId id, DeoptType &type, size_t &funcIndex);
void SetDeoptTypeInfo(BuiltinTypeId id, DeoptType &type, size_t &typedArrayRootHclassIndex,
size_t &typedArrayRootHclassOnHeapIndex);
void LowerLoadGetter(GateRef gate);
void LowerLoadSetter(GateRef gate);
void LowerPrototypeCheck(GateRef gate);

View File

@ -29,7 +29,7 @@ class OnHeap {
public:
static bool IsNone(OnHeapMode mode)
{
return mode == OnHeapMode::NONE;
return !(mode == OnHeapMode::ON_HEAP || mode == OnHeapMode::NOT_ON_HEAP);
}
static OnHeapMode Merge(OnHeapMode first, OnHeapMode second)

View File

@ -24,3 +24,13 @@ true
-Infinity
-0
2
true
false
true
1
2
false
1
false
2
3

View File

@ -24,3 +24,13 @@ true
-Infinity
-0
2
true
false
true
1
2
false
1
false
2
3

View File

@ -14,54 +14,98 @@
*/
// case 1
try {
var base = null;
var prop = {
toString: function () {
print("toString");
throw "111";
},
};
base[prop];
} catch (e) {
print("error");
function test1() {
try {
var base = null;
var prop = {
toString: function () {
print("toString");
throw "111";
},
};
base[prop];
} catch (e) {
print("error");
}
}
// case 2
print(Number.NaN != Number.NaN);
function test2() {
// case 2
print(Number.NaN != Number.NaN);
}
// case 3
function _test() {
this.x = 0.1;
this.x = 0.1;
}
function test3() {
var a = new _test();
print(a.x);
}
var a = new _test();
print(a.x);
// case 4: n mod d = r
// If r = 0 and n < -0, return -0.
print(1 / (-1 % 1));
print(1 / (-1 % -1));
print(1 / (-3 % 1));
print(1 / (-3 % -1));
print(1 / (-3 % 3));
print(1 / (-3 % -3));
print(1 / (-3.3 % 3.3));
print(1 / (-3.3 % -3.3));
function test4() {
// case 4: n mod d = r
// If r = 0 and n < -0, return -0.
print(1 / (-1 % 1));
print(1 / (-1 % -1));
print(1 / (-3 % 1));
print(1 / (-3 % -1));
print(1 / (-3 % 3));
print(1 / (-3 % -3));
print(1 / (-3.3 % 3.3));
print(1 / (-3.3 % -3.3));
}
// case 5: mod
var a = {};
a._toString = function (value) {
if (value === 0 && 1 / value === -Infinity) {
return "-0";
}
return String(value);
};
var x;
x = -1;
print(a._toString((x %= -1)));
function test5() {
// case 5: mod
var a = {};
a._toString = function (value) {
if (value === 0 && 1 / value === -Infinity) {
return "-0";
}
return String(value);
};
var x;
x = -1;
print(a._toString((x %= -1)));
}
function test6() {
// case6: prototype
var a = [0];
a.length = 3;
Object.prototype[2] = 2;
print(a[2]);
}
function test7() {
// onheap mode test
var onheap = new Uint8Array(1)
var onheap2 = new Uint8Array(1)
var notOnHeap = new Uint8Array(512 * 8 + 1)
onheap[0] = 1 // root on heap
notOnHeap[0] = 2 // root not onheap-
onheap2[0] = 3 // root on heap
print(ArkTools.isOnHeap(onheap));
print(ArkTools.isOnHeap(notOnHeap));
print(ArkTools.isOnHeap(onheap2));
print(onheap[0])
print(notOnHeap[0])
onheap.buffer // root not on heap
print(ArkTools.isOnHeap(onheap));
print(onheap[0])
onheap2.x = 2 // transition
onheap2.buffer // clone hclass and set not on heap
print(ArkTools.isOnHeap(onheap2));
print(onheap2.x)
print(onheap2[0])
}
test1()
test2()
test3()
test4()
test5()
test6()
test7()
// case6: prototype
var a = [0];
a.length = 3;
Object.prototype[2] = 2;
print(a[2]);