From 6978f167d6e7850f7809c20451114e57acb8cfb6 Mon Sep 17 00:00:00 2001 From: kz25t Date: Tue, 31 Oct 2023 11:11:55 +0800 Subject: [PATCH 1/2] Remove GetGlobalEnvObjHclass 1. Remove GetGlobalEnvObjHclass, and only GetGlobalEnvObj left. 2. The origin logic of GetGlobalEnvObjHclass is replaced by GetGlobalEnvObj and LoadConstOffset. Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I8CCW6 Signed-off-by: xiao-yupeng Change-Id: I30f0ac25531943e00187e133b0edcdfeffb8a7a9 Change-Id: I8df6256e8a6fea28271c721a72f9aee982f0bab6 --- ecmascript/compiler/circuit_builder.cpp | 11 ----------- ecmascript/compiler/circuit_builder.h | 1 - ecmascript/compiler/gate_accessor.cpp | 3 +-- ecmascript/compiler/later_elimination.cpp | 2 -- ecmascript/compiler/mcr_lowering.cpp | 15 --------------- ecmascript/compiler/mcr_lowering.h | 1 - ecmascript/compiler/mcr_opcodes.h | 1 - ecmascript/compiler/ntype_hcr_lowering.cpp | 4 +++- ecmascript/compiler/type_hcr_lowering.cpp | 4 +++- 9 files changed, 7 insertions(+), 35 deletions(-) diff --git a/ecmascript/compiler/circuit_builder.cpp b/ecmascript/compiler/circuit_builder.cpp index 82d85b9618..3c051de367 100644 --- a/ecmascript/compiler/circuit_builder.cpp +++ b/ecmascript/compiler/circuit_builder.cpp @@ -432,17 +432,6 @@ GateRef CircuitBuilder::GetGlobalEnvObj(GateRef env, size_t index) return newGate; } -GateRef CircuitBuilder::GetGlobalEnvObjHClass(GateRef env, size_t index) -{ - auto currentLabel = env_->GetCurrentLabel(); - auto currentDepend = currentLabel->GetDepend(); - auto newGate = GetCircuit()->NewGate(circuit_->GetGlobalEnvObjHClass(index), MachineType::I64, - { currentDepend, env }, - GateType::AnyType()); - currentLabel->SetDepend(newGate); - return newGate; -} - GateRef CircuitBuilder::GetGlobalConstantValue(ConstantIndex index) { auto currentLabel = env_->GetCurrentLabel(); diff --git a/ecmascript/compiler/circuit_builder.h b/ecmascript/compiler/circuit_builder.h index 1f63bf35e1..99e7e6691b 100644 --- a/ecmascript/compiler/circuit_builder.h +++ b/ecmascript/compiler/circuit_builder.h @@ -225,7 +225,6 @@ public: GateRef GetFunctionLexicalEnv(GateRef function); GateRef GetGlobalEnv(); GateRef GetGlobalEnvObj(GateRef env, size_t index); - GateRef GetGlobalEnvObjHClass(GateRef env, size_t index); GateRef GetGlobalConstantValue(ConstantIndex index); GateRef GetGlobalEnvValue(VariableType type, GateRef env, size_t index); GateRef GetGlobalObject(GateRef glue); diff --git a/ecmascript/compiler/gate_accessor.cpp b/ecmascript/compiler/gate_accessor.cpp index 77ed7a792a..2ca6ed1f81 100644 --- a/ecmascript/compiler/gate_accessor.cpp +++ b/ecmascript/compiler/gate_accessor.cpp @@ -133,8 +133,7 @@ bool GateAccessor::HasBranchWeight(GateRef gate) const size_t GateAccessor::GetIndex(GateRef gate) const { - ASSERT(GetOpCode(gate) == OpCode::GET_GLOBAL_ENV_OBJ_HCLASS || - GetOpCode(gate) == OpCode::GET_GLOBAL_CONSTANT_VALUE || + ASSERT(GetOpCode(gate) == OpCode::GET_GLOBAL_CONSTANT_VALUE || GetOpCode(gate) == OpCode::GET_GLOBAL_ENV_OBJ); Gate *gatePtr = circuit_->LoadGatePtr(gate); return gatePtr->GetOneParameterMetaData()->GetValue(); diff --git a/ecmascript/compiler/later_elimination.cpp b/ecmascript/compiler/later_elimination.cpp index f06ae40202..49730d5fab 100644 --- a/ecmascript/compiler/later_elimination.cpp +++ b/ecmascript/compiler/later_elimination.cpp @@ -36,7 +36,6 @@ GateRef LaterElimination::VisitGate(GateRef gate) case OpCode::GET_CONSTPOOL: case OpCode::GET_GLOBAL_ENV: case OpCode::GET_GLOBAL_ENV_OBJ: - case OpCode::GET_GLOBAL_ENV_OBJ_HCLASS: case OpCode::GET_GLOBAL_CONSTANT_VALUE: case OpCode::ARRAY_GUARDIAN_CHECK: case OpCode::HCLASS_STABLE_ARRAY_CHECK: @@ -152,7 +151,6 @@ bool LaterElimination::CheckReplacement(GateRef lhs, GateRef rhs) auto opcode = acc_.GetOpCode(lhs); switch (opcode) { case OpCode::GET_GLOBAL_ENV_OBJ: - case OpCode::GET_GLOBAL_ENV_OBJ_HCLASS: case OpCode::GET_GLOBAL_CONSTANT_VALUE: { if (acc_.GetIndex(lhs) != acc_.GetIndex(rhs)) { return false; diff --git a/ecmascript/compiler/mcr_lowering.cpp b/ecmascript/compiler/mcr_lowering.cpp index 60ac188070..5f90cd5562 100644 --- a/ecmascript/compiler/mcr_lowering.cpp +++ b/ecmascript/compiler/mcr_lowering.cpp @@ -55,9 +55,6 @@ GateRef MCRLowering::VisitGate(GateRef gate) case OpCode::GET_GLOBAL_ENV_OBJ: LowerGetGlobalEnvObj(gate); break; - case OpCode::GET_GLOBAL_ENV_OBJ_HCLASS: - LowerGetGlobalEnvObjHClass(gate); - break; case OpCode::GET_GLOBAL_CONSTANT_VALUE: LowerGetGlobalConstantValue(gate); break; @@ -659,18 +656,6 @@ void MCRLowering::LowerGetGlobalEnvObj(GateRef gate) acc_.ReplaceGate(gate, Circuit::NullGate(), builder_.GetDepend(), object); } -void MCRLowering::LowerGetGlobalEnvObjHClass(GateRef gate) -{ - Environment env(gate, circuit_, &builder_); - GateRef globalEnv = acc_.GetValueIn(gate, 0); - size_t index = acc_.GetIndex(gate); - GateRef offset = builder_.IntPtr(GlobalEnv::HEADER_SIZE + JSTaggedValue::TaggedTypeSize() * index); - GateRef object = builder_.Load(VariableType::JS_ANY(), globalEnv, offset); - auto hclass = builder_.Load(VariableType::JS_POINTER(), object, - builder_.IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET)); - acc_.ReplaceGate(gate, Circuit::NullGate(), builder_.GetDepend(), hclass); -} - void MCRLowering::LowerGetGlobalConstantValue(GateRef gate) { Environment env(gate, circuit_, &builder_); diff --git a/ecmascript/compiler/mcr_lowering.h b/ecmascript/compiler/mcr_lowering.h index 41bbd1bbfd..bb3e282596 100644 --- a/ecmascript/compiler/mcr_lowering.h +++ b/ecmascript/compiler/mcr_lowering.h @@ -56,7 +56,6 @@ private: void LowerCheckSupportAndConvert(GateRef gate, GateRef frameState); void LowerGetGlobalEnv(GateRef gate); void LowerGetGlobalEnvObj(GateRef gate); - void LowerGetGlobalEnvObjHClass(GateRef gate); void LowerGetGlobalConstantValue(GateRef gate); void LowerHeapAllocate(GateRef gate); void LowerInt32CheckRightIsZero(GateRef gate); diff --git a/ecmascript/compiler/mcr_opcodes.h b/ecmascript/compiler/mcr_opcodes.h index 06942c4c3e..58bbfc3f9b 100644 --- a/ecmascript/compiler/mcr_opcodes.h +++ b/ecmascript/compiler/mcr_opcodes.h @@ -68,7 +68,6 @@ namespace panda::ecmascript::kungfu { V(StableArrayCheck, STABLE_ARRAY_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \ V(RangeGuard, RANGE_GUARD, GateFlags::NO_WRITE, 1, 1, 1) \ V(GetGlobalEnvObj, GET_GLOBAL_ENV_OBJ, GateFlags::NO_WRITE, 0, 1, 1) \ - V(GetGlobalEnvObjHClass, GET_GLOBAL_ENV_OBJ_HCLASS, GateFlags::NO_WRITE, 0, 1, 1) \ V(GetGlobalConstantValue, GET_GLOBAL_CONSTANT_VALUE, GateFlags::NO_WRITE, 0, 1, 0) \ V(HClassStableArrayCheck, HCLASS_STABLE_ARRAY_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \ V(HeapAlloc, HEAP_ALLOC, GateFlags::NONE_FLAG, 1, 1, 1) \ diff --git a/ecmascript/compiler/ntype_hcr_lowering.cpp b/ecmascript/compiler/ntype_hcr_lowering.cpp index 7f9853114f..1bd4e46611 100644 --- a/ecmascript/compiler/ntype_hcr_lowering.cpp +++ b/ecmascript/compiler/ntype_hcr_lowering.cpp @@ -132,7 +132,9 @@ GateRef NTypeHCRLowering::NewJSArrayLiteral(GateRef gate, GateRef elements, Gate hclass = builder_.GetGlobalConstantValue(hclassIndex); } else { GateRef globalEnv = builder_.GetGlobalEnv(); - hclass = builder_.GetGlobalEnvObjHClass(globalEnv, GlobalEnv::ARRAY_FUNCTION_INDEX); + GateRef arrFunObj = builder_.GetGlobalEnvObj(globalEnv, GlobalEnv::ARRAY_FUNCTION_INDEX); + hclass = builder_.LoadConstOffset(VariableType::JS_POINTER(), arrFunObj, + JSFunction::PROTO_OR_DYNCLASS_OFFSET); } JSHandle arrayFunc(tsManager_->GetEcmaVM()->GetGlobalEnv()->GetArrayFunction()); diff --git a/ecmascript/compiler/type_hcr_lowering.cpp b/ecmascript/compiler/type_hcr_lowering.cpp index 869e1deec8..6e43930eed 100644 --- a/ecmascript/compiler/type_hcr_lowering.cpp +++ b/ecmascript/compiler/type_hcr_lowering.cpp @@ -312,7 +312,9 @@ void TypeHCRLowering::LowerTypedArrayCheck(GateRef gate) GateRef glueGlobalEnv = builder_.GetGlobalEnv(); GateRef receiver = acc_.GetValueIn(gate, 0); GateRef receiverHClass = builder_.LoadHClass(receiver); - GateRef protoOrHclass = builder_.GetGlobalEnvObjHClass(glueGlobalEnv, typedArrayFuncIndex); + GateRef arrFuncObj = builder_.GetGlobalEnvObj(glueGlobalEnv, GlobalEnv::ARRAY_FUNCTION_INDEX); + GateRef protoOrHclass = builder_.LoadConstOffset(VariableType::JS_POINTER(), arrFuncObj, + builder_.IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET)); GateRef check = builder_.Equal(receiverHClass, protoOrHclass); builder_.DeoptCheck(check, frameState, deoptType); -- Gitee From 772137d14bcc35dbb47526747d9b72ced6fdefa1 Mon Sep 17 00:00:00 2001 From: kz25t Date: Tue, 7 Nov 2023 10:30:30 +0800 Subject: [PATCH 2/2] Optimizes AOT LdObjByName for Set.size and Map.size New Function for optimizes Set.size and Map.size Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I8EDHZ Signed-off-by: kz25t Change-Id: I6868664cc93d7df57605f138b3006c305fd2803b --- ecmascript/compiler/circuit_builder.h | 2 ++ ecmascript/compiler/mcr_circuit_builder.cpp | 24 +++++++++++++ ecmascript/compiler/mcr_opcodes.h | 2 ++ .../compiler/type_bytecode_lowering.cpp | 36 ++++++++++++++++++- ecmascript/compiler/type_bytecode_lowering.h | 2 ++ ecmascript/compiler/type_hcr_lowering.cpp | 35 +++++++++++++++++- ecmascript/compiler/type_hcr_lowering.h | 2 ++ ecmascript/global_env_constants.h | 1 + 8 files changed, 102 insertions(+), 2 deletions(-) diff --git a/ecmascript/compiler/circuit_builder.h b/ecmascript/compiler/circuit_builder.h index 99e7e6691b..a793f46268 100644 --- a/ecmascript/compiler/circuit_builder.h +++ b/ecmascript/compiler/circuit_builder.h @@ -502,6 +502,8 @@ public: GateRef LoadArrayLength(GateRef array); inline GateRef LoadFromTaggedArray(GateRef array, size_t index); GateRef LoadStringLength(GateRef string); + GateRef LoadMapSize(GateRef map); + GateRef LoadSetSize(GateRef set); GateRef LoadConstOffset(VariableType type, GateRef receiver, size_t offset); GateRef TypedCall(GateRef hirGate, std::vector args, bool isNoGC); GateRef TypedFastCall(GateRef hirGate, std::vector args, bool isNoGC); diff --git a/ecmascript/compiler/mcr_circuit_builder.cpp b/ecmascript/compiler/mcr_circuit_builder.cpp index 81e35dc0b1..175c3c8cd0 100644 --- a/ecmascript/compiler/mcr_circuit_builder.cpp +++ b/ecmascript/compiler/mcr_circuit_builder.cpp @@ -693,6 +693,30 @@ GateRef CircuitBuilder::LoadStringLength(GateRef string) return ret; } +GateRef CircuitBuilder::LoadMapSize(GateRef map) +{ + auto currentLabel = env_->GetCurrentLabel(); + auto currentControl = currentLabel->GetControl(); + auto currentDepend = currentLabel->GetDepend(); + auto ret = GetCircuit()->NewGate(circuit_->LoadMapSize(), MachineType::I64, + { currentControl, currentDepend, map }, GateType::IntType()); + currentLabel->SetControl(ret); + currentLabel->SetDepend(ret); + return ret; +} + +GateRef CircuitBuilder::LoadSetSize(GateRef set) +{ + auto currentLabel = env_->GetCurrentLabel(); + auto currentControl = currentLabel->GetControl(); + auto currentDepend = currentLabel->GetDepend(); + auto ret = GetCircuit()->NewGate(circuit_->LoadSetSize(), MachineType::I64, + { currentControl, currentDepend, set }, GateType::IntType()); + currentLabel->SetControl(ret); + currentLabel->SetDepend(ret); + return ret; +} + GateRef CircuitBuilder::LoadConstOffset(VariableType type, GateRef receiver, size_t offset) { auto currentLabel = env_->GetCurrentLabel(); diff --git a/ecmascript/compiler/mcr_opcodes.h b/ecmascript/compiler/mcr_opcodes.h index 58bbfc3f9b..e1a3e3e7b5 100644 --- a/ecmascript/compiler/mcr_opcodes.h +++ b/ecmascript/compiler/mcr_opcodes.h @@ -42,6 +42,8 @@ namespace panda::ecmascript::kungfu { V(LoadSetter, LOAD_SETTER, GateFlags::NO_WRITE, 0, 1, 2) \ V(LoadArrayLength, LOAD_ARRAY_LENGTH, GateFlags::NO_WRITE, 1, 1, 1) \ V(LoadStringLength, LOAD_STRING_LENGTH, GateFlags::NO_WRITE, 1, 1, 1) \ + V(LoadMapSize, LOAD_MAP_SIZE, GateFlags::NO_WRITE, 1, 1, 1) \ + V(LoadSetSize, LOAD_SET_SIZE, GateFlags::NO_WRITE, 1, 1, 1) \ V(StartAllocate, START_ALLOCATE, GateFlags::NONE_FLAG, 0, 1, 0) \ V(StoreProperty, STORE_PROPERTY, GateFlags::NONE_FLAG, 1, 1, 3) \ V(StorePropertyNoBarrier, STORE_PROPERTY_NO_BARRIER, GateFlags::NONE_FLAG, 1, 1, 3) \ diff --git a/ecmascript/compiler/type_bytecode_lowering.cpp b/ecmascript/compiler/type_bytecode_lowering.cpp index e603d44b49..b8358e8d4e 100644 --- a/ecmascript/compiler/type_bytecode_lowering.cpp +++ b/ecmascript/compiler/type_bytecode_lowering.cpp @@ -745,7 +745,19 @@ bool TypeBytecodeLowering::TryLowerTypedLdObjByNameForBuiltin(GateRef gate, JSTa return true; } } - // (2) other functions + // (2) get size + EcmaString *sizeString = EcmaString::Cast(thread_->GlobalConstants()->GetSizeString().GetTaggedObject()); + if (propString == sizeString) { + if (type == BuiltinTypeId::MAP) { + LowerTypedLdMapSize(gate); + return true; + } + if (type == BuiltinTypeId::SET) { + LowerTypedLdSetSize(gate); + return true; + } + } + // (3) other functions return TryLowerTypedLdObjByNameForBuiltinMethod(gate, key, type); } @@ -807,6 +819,28 @@ void TypeBytecodeLowering::LowerTypedLdStringLength(GateRef gate) acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), result); } +void TypeBytecodeLowering::LowerTypedLdMapSize(GateRef gate) +{ + AddProfiling(gate); + GateRef map = acc_.GetValueIn(gate, 2); + if (!Uncheck()) { + builder_.BuiltinPrototypeHClassCheck(map, BuiltinTypeId::MAP); + } + GateRef result = builder_.LoadMapSize(map); + acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), result); +} + +void TypeBytecodeLowering::LowerTypedLdSetSize(GateRef gate) +{ + AddProfiling(gate); + GateRef set = acc_.GetValueIn(gate, 2); + if (!Uncheck()) { + builder_.BuiltinPrototypeHClassCheck(set, BuiltinTypeId::SET); + } + GateRef result = builder_.LoadSetSize(set); + acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), result); +} + bool TypeBytecodeLowering::TryLowerTypedLdObjByNameForBuiltinMethod(GateRef gate, JSTaggedValue key, BuiltinTypeId type) { std::optional protoField = ToGlobelEnvPrototypeField(type); diff --git a/ecmascript/compiler/type_bytecode_lowering.h b/ecmascript/compiler/type_bytecode_lowering.h index 017c0343ba..54a45cdea7 100644 --- a/ecmascript/compiler/type_bytecode_lowering.h +++ b/ecmascript/compiler/type_bytecode_lowering.h @@ -103,6 +103,8 @@ private: void LowerTypedLdArrayLength(GateRef gate); void LowerTypedLdTypedArrayLength(GateRef gate); void LowerTypedLdStringLength(GateRef gate); + void LowerTypedLdMapSize(GateRef gate); + void LowerTypedLdSetSize(GateRef gate); void LowerTypedLdObjByIndex(GateRef gate); void LowerTypedStObjByIndex(GateRef gate); diff --git a/ecmascript/compiler/type_hcr_lowering.cpp b/ecmascript/compiler/type_hcr_lowering.cpp index 6e43930eed..ef4750adf9 100644 --- a/ecmascript/compiler/type_hcr_lowering.cpp +++ b/ecmascript/compiler/type_hcr_lowering.cpp @@ -20,9 +20,12 @@ #include "ecmascript/deoptimizer/deoptimizer.h" #include "ecmascript/js_arraybuffer.h" #include "ecmascript/js_native_pointer.h" +#include "ecmascript/js_map.h" +#include "ecmascript/js_set.h" +#include "ecmascript/linked_hash_table.h" +#include "ecmascript/message_string.h" #include "ecmascript/subtyping_operator.h" #include "ecmascript/vtable.h" -#include "ecmascript/message_string.h" namespace panda::ecmascript::kungfu { GateRef TypeHCRLowering::VisitGate(GateRef gate) { @@ -90,6 +93,12 @@ GateRef TypeHCRLowering::VisitGate(GateRef gate) case OpCode::CALL_SETTER: LowerCallSetter(gate, glue); break; + case OpCode::LOAD_MAP_SIZE: + LowerLoadMapSize(gate); + break; + case OpCode::LOAD_SET_SIZE: + LowerLoadSetSize(gate); + break; case OpCode::LOAD_ARRAY_LENGTH: LowerLoadArrayLength(gate); break; @@ -765,6 +774,30 @@ void TypeHCRLowering::LowerLoadArrayLength(GateRef gate) acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result); } +void TypeHCRLowering::LowerLoadMapSize(GateRef gate) +{ + Environment env(gate, circuit_, &builder_); + GateRef map = acc_.GetValueIn(gate, 0); + GateRef linkedMap = builder_.LoadConstOffset(VariableType::JS_POINTER(), map, JSMap::LINKED_MAP_OFFSET); + // Note: the result is a JSTaggedValue + GateRef taggedResult = builder_.LoadConstOffset(VariableType::JS_ANY(), linkedMap, + TaggedArray::DATA_OFFSET + LinkedHashMap::NUMBER_OF_ELEMENTS_INDEX); + acc_.SetGateType(gate, GateType::NumberType()); + acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), taggedResult); +} + +void TypeHCRLowering::LowerLoadSetSize(GateRef gate) +{ + Environment env(gate, circuit_, &builder_); + GateRef set = acc_.GetValueIn(gate, 0); + GateRef linkedSet = builder_.LoadConstOffset(VariableType::JS_POINTER(), set, JSSet::LINKED_SET_OFFSET); + // Note: the result is a JSTaggedValue + GateRef taggedResult = builder_.LoadConstOffset(VariableType::JS_ANY(), linkedSet, + TaggedArray::DATA_OFFSET + LinkedHashSet::NUMBER_OF_ELEMENTS_INDEX); + acc_.SetGateType(gate, GateType::NumberType()); + acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), taggedResult); +} + GateRef TypeHCRLowering::GetElementSize(BuiltinTypeId id) { GateRef elementSize = Circuit::NullGate(); diff --git a/ecmascript/compiler/type_hcr_lowering.h b/ecmascript/compiler/type_hcr_lowering.h index 84db53a9b5..20bfadb109 100644 --- a/ecmascript/compiler/type_hcr_lowering.h +++ b/ecmascript/compiler/type_hcr_lowering.h @@ -141,6 +141,8 @@ private: void LowerCallGetter(GateRef gate, GateRef glue); void LowerStoreProperty(GateRef gate); void LowerCallSetter(GateRef gate, GateRef glue); + void LowerLoadMapSize(GateRef gate); + void LowerLoadSetSize(GateRef gate); void LowerLoadArrayLength(GateRef gate); void LowerStoreElement(GateRef gate, GateRef glue); void LowerLoadElement(GateRef gate); diff --git a/ecmascript/global_env_constants.h b/ecmascript/global_env_constants.h index b15ca46752..9e387309a2 100644 --- a/ecmascript/global_env_constants.h +++ b/ecmascript/global_env_constants.h @@ -173,6 +173,7 @@ class ObjectFactory; V(PrototypeString, PROTOTYPE_STRING_INDEX, "prototype") \ V(LengthString, LENGTH_STRING_INDEX, "length") \ V(ValueString, VALUE_STRING_INDEX, "value") \ + V(SizeString, SIZE_STRING_INDEX, "size") \ V(SetString, SET_STRING_INDEX, "set") \ V(GetString, GET_STRING_INDEX, "get") \ V(WritableString, WRITABLE_STRING_INDEX, "writable") \ -- Gitee