!4209 Remove Load/StoreElement elementsLength check

Merge pull request !4209 from 孙哲/master
This commit is contained in:
openharmony_ci 2023-06-08 14:33:33 +00:00 committed by Gitee
commit b2d545c02a
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
13 changed files with 99 additions and 92 deletions

View File

@ -219,7 +219,7 @@ DECLARE_BUILTINS(IndexOf)
auto env = GetEnvironment();
DEFVARIABLE(res, VariableType::JS_ANY(), IntToTaggedPtr(Int32(-1)));
DEFVARIABLE(pos, VariableType::INT32(), Int32(0));
Label objNotUndefinedAndNull(env);
Label isString(env);
Label isSearchString(env);
@ -569,7 +569,7 @@ DECLARE_BUILTINS(VectorForEach)
Label exit(env);
Label slowPath(env);
ContainersStubBuilder containersBuilder(this);
containersBuilder.ContainersCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
&slowPath, ContainersType::VECTOR_FOREACH);
@ -590,7 +590,7 @@ DECLARE_BUILTINS(VectorReplaceAllElements)
Label exit(env);
Label slowPath(env);
ContainersStubBuilder containersBuilder(this);
containersBuilder.ContainersCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
&slowPath, ContainersType::VECTOR_REPLACEALLELEMENTS);
@ -611,7 +611,7 @@ DECLARE_BUILTINS(StackForEach)
Label exit(env);
Label slowPath(env);
ContainersStubBuilder containersBuilder(this);
containersBuilder.ContainersCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
&slowPath, ContainersType::STACK_FOREACH);
@ -632,7 +632,7 @@ DECLARE_BUILTINS(PlainArrayForEach)
Label exit(env);
Label slowPath(env);
ContainersStubBuilder containersBuilder(this);
containersBuilder.ContainersCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
&slowPath, ContainersType::PLAINARRAY_FOREACH);
@ -653,7 +653,7 @@ DECLARE_BUILTINS(QueueForEach)
Label exit(env);
Label slowPath(env);
ContainersStubBuilder containersBuilder(this);
containersBuilder.QueueCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
&slowPath, ContainersType::QUEUE_FOREACH);
@ -674,7 +674,7 @@ DECLARE_BUILTINS(DequeForEach)
Label exit(env);
Label slowPath(env);
ContainersStubBuilder containersBuilder(this);
containersBuilder.DequeCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
&slowPath, ContainersType::DEQUE_FOREACH);
@ -821,7 +821,7 @@ DECLARE_BUILTINS(ArrayListForEach)
Label exit(env);
Label slowPath(env);
ContainersStubBuilder containersBuilder(this);
containersBuilder.ContainersCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
&slowPath, ContainersType::ARRAYLIST_FOREACH);
@ -842,7 +842,7 @@ DECLARE_BUILTINS(ArrayListReplaceAllElements)
Label exit(env);
Label slowPath(env);
ContainersStubBuilder containersBuilder(this);
containersBuilder.ContainersCommonFuncCall(glue, thisValue, numArgs, &res, &exit,
&slowPath, ContainersType::ARRAYLIST_REPLACEALLELEMENTS);
@ -942,7 +942,7 @@ DECLARE_BUILTINS(FunctionPrototypeApply)
}
}
}
Bind(&slowPath);
{
res = CallSlowPath(nativeCode, glue, thisValue, numArgs, func, newTarget);
@ -1157,12 +1157,13 @@ DECLARE_BUILTINS(ArrayConstructor)
}
Bind(&arrayCreate);
{
NewObjectStubBuilder newBuilder(this);
newBuilder.SetParameters(glue, 0);
Label afterNew(env);
newBuilder.NewJSObject(&res, &afterNew, intialHClass);
Bind(&afterNew);
Label lengthValid(env);
Branch(Int64GreaterThan(*arrayLength, Int64(JSObject::MAX_GAP)), &slowPath, &lengthValid);
Bind(&lengthValid);
{
NewObjectStubBuilder newBuilder(this);
newBuilder.SetParameters(glue, 0);
res = newBuilder.NewJSArrayWithSize(intialHClass, *arrayLength);
GateRef lengthOffset = IntPtr(JSArray::LENGTH_OFFSET);
Store(VariableType::JS_ANY(), glue, *res, lengthOffset, Int64ToTaggedInt(*arrayLength));
GateRef accessor = GetGlobalConstantValue(VariableType::JS_ANY(), glue,

View File

@ -880,21 +880,21 @@ GateRef CircuitBuilder::TypedConditionJump(GateRef x, GateType xType)
}
template <TypedLoadOp Op>
GateRef CircuitBuilder::LoadElement(GateRef receiver, GateRef index, GateRef length)
GateRef CircuitBuilder::LoadElement(GateRef receiver, GateRef index)
{
auto opIdx = static_cast<uint64_t>(Op);
auto currentLabel = env_->GetCurrentLabel();
auto currentControl = currentLabel->GetControl();
auto currentDepend = currentLabel->GetDepend();
auto ret = GetCircuit()->NewGate(GetCircuit()->LoadElement(opIdx), MachineType::I64,
{currentControl, currentDepend, receiver, index, length}, GateType::AnyType());
{currentControl, currentDepend, receiver, index}, GateType::AnyType());
currentLabel->SetControl(ret);
currentLabel->SetDepend(ret);
return ret;
}
template <TypedStoreOp Op>
GateRef CircuitBuilder::StoreElement(GateRef receiver, GateRef index, GateRef value, GateRef length)
GateRef CircuitBuilder::StoreElement(GateRef receiver, GateRef index, GateRef value)
{
auto opIdx = static_cast<uint64_t>(Op);
auto currentLabel = env_->GetCurrentLabel();
@ -902,7 +902,7 @@ GateRef CircuitBuilder::StoreElement(GateRef receiver, GateRef index, GateRef va
auto currentDepend = currentLabel->GetDepend();
auto ret =
GetCircuit()->NewGate(GetCircuit()->StoreElement(opIdx), MachineType::NOVALUE,
{currentControl, currentDepend, receiver, index, value, length}, GateType::AnyType());
{currentControl, currentDepend, receiver, index, value}, GateType::AnyType());
currentLabel->SetControl(ret);
currentLabel->SetDepend(ret);
return ret;

View File

@ -501,9 +501,9 @@ public:
// middle ir: object operations
GateRef ToLength(GateRef receiver);
template<TypedLoadOp Op>
GateRef LoadElement(GateRef receiver, GateRef index, GateRef length);
GateRef LoadElement(GateRef receiver, GateRef index);
template<TypedStoreOp Op>
GateRef StoreElement(GateRef receiver, GateRef index, GateRef value, GateRef length);
GateRef StoreElement(GateRef receiver, GateRef index, GateRef value);
GateRef LoadProperty(GateRef receiver, GateRef propertyLookupResult, bool isFunction);
GateRef StoreProperty(GateRef receiver, GateRef propertyLookupResult, GateRef value);
GateRef LoadArrayLength(GateRef array);

View File

@ -300,8 +300,8 @@ std::string MachineTypeToStr(MachineType machineType);
V(HeapAlloc, HEAP_ALLOC, GateFlags::NONE_FLAG, 1, 1, 1) \
V(LoadConstOffset, LOAD_CONST_OFFSET, GateFlags::NO_WRITE, 0, 1, 1) \
V(StoreConstOffset, STORE_CONST_OFFSET, GateFlags::NONE_FLAG, 1, 1, 2) \
V(LoadElement, LOAD_ELEMENT, GateFlags::NO_WRITE, 1, 1, 3) \
V(StoreElement, STORE_ELEMENT, GateFlags::NONE_FLAG, 1, 1, 4) \
V(LoadElement, LOAD_ELEMENT, GateFlags::NO_WRITE, 1, 1, 2) \
V(StoreElement, STORE_ELEMENT, GateFlags::NONE_FLAG, 1, 1, 3) \
V(RestoreRegister, RESTORE_REGISTER, GateFlags::NONE_FLAG, 0, 1, 0) \
V(Constant, CONSTANT, GateFlags::NONE_FLAG, 0, 0, 0) \
V(RelocatableData, RELOCATABLE_DATA, GateFlags::NONE_FLAG, 0, 0, 0) \

View File

@ -59,6 +59,23 @@ void NewObjectStubBuilder::NewLexicalEnv(Variable *result, Label *exit, GateRef
}
}
GateRef NewObjectStubBuilder::NewJSArrayWithSize(GateRef hclass, GateRef size)
{
auto env = GetEnvironment();
Label entry(env);
Label exit(env);
env->SubCfgEntry(&entry);
GateRef result = NewJSObject(glue_, hclass);
DEFVARIABLE(array, VariableType::JS_ANY(), Undefined());
NewTaggedArrayChecked(&array, TruncInt64ToInt32(size), &exit);
Bind(&exit);
auto arrayRet = *array;
env->SubCfgExit();
SetElementsArray(VariableType::JS_POINTER(), glue_, result, arrayRet);
return result;
}
void NewObjectStubBuilder::NewJSObject(Variable *result, Label *exit, GateRef hclass)
{
auto env = GetEnvironment();
@ -122,6 +139,29 @@ GateRef NewObjectStubBuilder::NewJSObject(GateRef glue, GateRef hclass)
return ret;
}
void NewObjectStubBuilder::NewTaggedArrayChecked(Variable *result, GateRef len, Label *exit)
{
auto env = GetEnvironment();
size_ = ComputeTaggedArraySize(ZExtInt32ToPtr(len));
Label afterAllocate(env);
// Be careful. NO GC is allowed when initization is not complete.
AllocateInYoung(result, &afterAllocate);
Bind(&afterAllocate);
Label noException(env);
Branch(TaggedIsException(result->ReadVariable()), exit, &noException);
Bind(&noException);
{
auto hclass = GetGlobalConstantValue(
VariableType::JS_POINTER(), glue_, ConstantIndex::ARRAY_CLASS_INDEX);
StoreHClass(glue_, result->ReadVariable(), hclass);
Label afterInitialize(env);
InitializeTaggedArrayWithSpeicalValue(&afterInitialize,
result->ReadVariable(), Hole(), Int32(0), len);
Bind(&afterInitialize);
Jump(exit);
}
}
GateRef NewObjectStubBuilder::NewTaggedArray(GateRef glue, GateRef len)
{
auto env = GetEnvironment();
@ -147,29 +187,7 @@ GateRef NewObjectStubBuilder::NewTaggedArray(GateRef glue, GateRef len)
Branch(Int32LessThan(len, Int32(MAX_TAGGED_ARRAY_LENGTH)), &next, &slowPath);
Bind(&next);
{
size_ = ComputeTaggedArraySize(ZExtInt32ToPtr(len));
Label afterAllocate(env);
// Be careful. NO GC is allowed when initization is not complete.
AllocateInYoung(&result, &afterAllocate);
Bind(&afterAllocate);
Label hasPendingException(env);
Label noException(env);
Branch(TaggedIsException(*result), &hasPendingException, &noException);
Bind(&noException);
{
auto hclass = GetGlobalConstantValue(
VariableType::JS_POINTER(), glue_, ConstantIndex::ARRAY_CLASS_INDEX);
StoreHClass(glue_, *result, hclass);
Label afterInitialize(env);
InitializeTaggedArrayWithSpeicalValue(&afterInitialize,
*result, Hole(), Int32(0), len);
Bind(&afterInitialize);
Jump(&exit);
}
Bind(&hasPendingException);
{
Jump(&exit);
}
NewTaggedArrayChecked(&result, len, &exit);
}
Bind(&slowPath);
{

View File

@ -44,7 +44,9 @@ public:
void NewLexicalEnv(Variable *result, Label *exit, GateRef numSlots, GateRef parent);
void NewJSObject(Variable *result, Label *exit, GateRef hclass);
GateRef NewJSObject(GateRef glue, GateRef hclass);
GateRef NewJSArray(GateRef glue, GateRef hclass);
GateRef NewTaggedArray(GateRef glue, GateRef len);
GateRef NewJSArrayWithSize(GateRef hclass, GateRef size);
void NewArgumentsList(Variable *result, Label *exit, GateRef sp, GateRef startIdx, GateRef numArgs);
void NewArgumentsObj(Variable *result, Label *exit, GateRef argumentsList, GateRef numArgs);
void AllocLineStringObject(Variable *result, Label *exit, GateRef length, bool compressed);
@ -56,6 +58,7 @@ public:
GateRef NewThisObjectChecked(GateRef glue, GateRef ctor);
GateRef CreateEmptyArray(GateRef glue);
GateRef CreateArrayWithBuffer(GateRef glue, GateRef index, GateRef jsFunc);
void NewTaggedArrayChecked(Variable *result, GateRef len, Label *exit);
private:
static constexpr int MAX_TAGGED_ARRAY_LENGTH = 50;

View File

@ -2471,8 +2471,7 @@ GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef
Branch(IsJsCOWArray(*holder), &isJsCOWArray, &isNotJsCOWArray);
Bind(&isJsCOWArray);
{
CallRuntime(glue, RTSTUB_ID(CheckAndCopyArray), {*holder});
GateRef newElements = GetElementsArray(*holder);
GateRef newElements = CallRuntime(glue, RTSTUB_ID(CheckAndCopyArray), {*holder});
SetValueToTaggedArray(VariableType::JS_ANY(), glue, newElements, index, value);
returnValue = Undefined();
Jump(&exit);

View File

@ -669,7 +669,7 @@ void TSHCRLowering::LowerTypedLdObjByIndex(GateRef gate)
GateRef result = Circuit::NullGate();
if (tsManager_->IsFloat32ArrayType(receiverType)) {
result = builder_.LoadElement<TypedLoadOp::FLOAT32ARRAY_LOAD_ELEMENT>(receiver, index, builder_.Undefined());
result = builder_.LoadElement<TypedLoadOp::FLOAT32ARRAY_LOAD_ELEMENT>(receiver, index);
} else {
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
@ -705,7 +705,7 @@ void TSHCRLowering::LowerTypedStObjByIndex(GateRef gate)
builder_.IndexCheck(receiverType, receiver, index);
if (tsManager_->IsFloat32ArrayType(receiverType)) {
builder_.StoreElement<TypedStoreOp::FLOAT32ARRAY_STORE_ELEMENT>(receiver, index, value, builder_.Undefined());
builder_.StoreElement<TypedStoreOp::FLOAT32ARRAY_STORE_ELEMENT>(receiver, index, value);
} else {
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
@ -741,7 +741,7 @@ void TSHCRLowering::LowerTypedLdObjByValue(GateRef gate, bool isThis)
builder_.StableArrayCheck(receiver);
GateRef length = builder_.LoadArrayLength(receiver);
propKey = builder_.IndexCheck(receiverType, length, propKey);
GateRef result = builder_.LoadElement<TypedLoadOp::ARRAY_LOAD_ELEMENT>(receiver, propKey, length);
GateRef result = builder_.LoadElement<TypedLoadOp::ARRAY_LOAD_ELEMENT>(receiver, propKey);
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), result);
}
@ -763,7 +763,7 @@ void TSHCRLowering::LowerTypedStObjByValue(GateRef gate)
builder_.StableArrayCheck(receiver);
GateRef length = builder_.LoadArrayLength(receiver);
builder_.IndexCheck(receiverType, length, propKey);
builder_.StoreElement<TypedStoreOp::ARRAY_STORE_ELEMENT>(receiver, propKey, value, length);
builder_.StoreElement<TypedStoreOp::ARRAY_STORE_ELEMENT>(receiver, propKey, value);
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), Circuit::NullGate());
}

View File

@ -537,23 +537,10 @@ void TypeMCRLowering::LowerArrayLoadElement(GateRef gate)
Environment env(gate, circuit_, &builder_);
GateRef receiver = acc_.GetValueIn(gate, 0);
GateRef index = acc_.GetValueIn(gate, 1);
GateRef length = acc_.GetValueIn(gate, 2); // length
ASSERT(!acc_.IsConstantUndefined(length));
GateRef element = builder_.LoadConstOffset(VariableType::JS_POINTER(), receiver, JSObject::ELEMENTS_OFFSET);
GateRef arrayLength = builder_.GetLengthFromTaggedArray(element);
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.UndefineConstant());
Label accessValue(&builder_);
Label exit(&builder_);
GateRef hasEntityValue = builder_.Int32LessThanOrEqual(length, arrayLength);
builder_.Branch(hasEntityValue, &accessValue, &exit);
builder_.Bind(&accessValue);
{
result = builder_.GetValueFromTaggedArray(element, index);
result = builder_.ConvertHoleAsUndefined(*result);
builder_.Jump(&exit);
};
builder_.Bind(&exit);
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
GateRef result = builder_.GetValueFromTaggedArray(element, index);
result = builder_.ConvertHoleAsUndefined(result);
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
}
// for Float32Array
@ -619,15 +606,6 @@ void TypeMCRLowering::LowerArrayStoreElement(GateRef gate, GateRef glue)
GateRef receiver = acc_.GetValueIn(gate, 0); // 0: receiver
GateRef index = acc_.GetValueIn(gate, 1); // 1: index
GateRef value = acc_.GetValueIn(gate, 2); // 2: value
GateRef length = acc_.GetValueIn(gate, 3); // 3: length
ASSERT(!acc_.IsConstantUndefined(length));
GateRef currentDepend = builder_.GetDepend();
GateRef element = builder_.LoadConstOffset(VariableType::JS_POINTER(), receiver, JSObject::ELEMENTS_OFFSET);
GateRef arrayLength = builder_.GetLengthFromTaggedArray(element);
GateRef hasEntityValue = builder_.Int32LessThanOrEqual(length, arrayLength);
GateRef frameState = acc_.FindNearestFrameState(currentDepend);
builder_.DeoptCheck(hasEntityValue, frameState, DeoptType::NOTSARRAY);
Label storeWithCOWArray(&builder_);
Label storeDirectly(&builder_);
@ -635,13 +613,13 @@ void TypeMCRLowering::LowerArrayStoreElement(GateRef gate, GateRef glue)
builder_.Branch(builder_.IsJsCOWArray(receiver), &storeWithCOWArray, &storeDirectly);
builder_.Bind(&storeWithCOWArray);
{
LowerCallRuntime(glue, gate, RTSTUB_ID(CheckAndCopyArray), {receiver}, true);
GateRef newElement = builder_.LoadConstOffset(VariableType::JS_POINTER(), receiver, JSObject::ELEMENTS_OFFSET);
GateRef newElement = LowerCallRuntime(glue, gate, RTSTUB_ID(CheckAndCopyArray), {receiver}, true);
builder_.SetValueToTaggedArray(VariableType::JS_ANY(), glue, newElement, index, value);
builder_.Jump(&exit);
}
builder_.Bind(&storeDirectly);
{
GateRef element = builder_.LoadConstOffset(VariableType::JS_POINTER(), receiver, JSObject::ELEMENTS_OFFSET);
builder_.SetValueToTaggedArray(VariableType::JS_ANY(), glue, element, index, value);
builder_.Jump(&exit);
}

View File

@ -81,7 +81,7 @@ JSHandle<JSTaggedValue> JSArray::ArrayCreate(JSThread *thread, JSTaggedNumber le
// 10. Perform OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor{[[Value]]: length, [[Writable]]:
// true, [[Enumerable]]: false, [[Configurable]]: false}).
JSArray::Cast(*obj)->SetArrayLength(thread, normalArrayLength);
JSArray::SetCapacity(thread, obj, 0, normalArrayLength);
return JSHandle<JSTaggedValue>(obj);
}

View File

@ -305,7 +305,7 @@ DEF_RUNTIME_STUBS(CheckAndCopyArray)
JSTaggedType argReceiver = GetTArg(argv, argc, 0); // 0: means the zeroth parameter
JSHandle<JSArray> receiverHandle(thread, reinterpret_cast<JSArray *>(argReceiver));
JSArray::CheckAndCopyArray(thread, receiverHandle);
return JSTaggedValue::Hole().GetRawData();
return receiverHandle->GetElements().GetRawData();
}
DEF_RUNTIME_STUBS(NewEcmaHClass)

View File

@ -13,3 +13,4 @@
true
true
true

View File

@ -16,18 +16,25 @@
declare function print(arg:any):string;
class A{}
let array:A[] = [undefined];
for (let i = 0; i < array.length; i++) {
print(array[i]===undefined);
}
class ParticleSystemCPU {
private _arrayTest: number[];
constructor() {
this._arrayTest = new Array(10);
print(this._arrayTest[9] === undefined);
function testLiteralArray() {
let array:A[] = [undefined];
for (let i = 0; i < array.length; i++) {
print(array[i]===undefined);
}
}
var system: ParticleSystemCPU[] = [new ParticleSystemCPU()];
testLiteralArray();
function testLargeHolyArray() {
let arrayTest = new Array(10000);
print(arrayTest[9] === undefined);
}
testLargeHolyArray();
function testHolyArray() {
let arrayTest = new Array(10);
print(arrayTest[9] === undefined);
}
testHolyArray();