mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 10:09:54 +00:00
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:
parent
02de93935e
commit
4604a5d086
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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_);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -24,3 +24,13 @@ true
|
||||
-Infinity
|
||||
-0
|
||||
2
|
||||
true
|
||||
false
|
||||
true
|
||||
1
|
||||
2
|
||||
false
|
||||
1
|
||||
false
|
||||
2
|
||||
3
|
||||
|
@ -24,3 +24,13 @@ true
|
||||
-Infinity
|
||||
-0
|
||||
2
|
||||
true
|
||||
false
|
||||
true
|
||||
1
|
||||
2
|
||||
false
|
||||
1
|
||||
false
|
||||
2
|
||||
3
|
||||
|
@ -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]);
|
||||
|
Loading…
Reference in New Issue
Block a user