diff --git a/ecmascript/compiler/circuit_builder.cpp b/ecmascript/compiler/circuit_builder.cpp index 3ff4401777f0715a92245d7f1f6e52cab8c7513f..03afdf14de9003f8a4c6e33e05b434c5140b1bd3 100644 --- a/ecmascript/compiler/circuit_builder.cpp +++ b/ecmascript/compiler/circuit_builder.cpp @@ -451,17 +451,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 20d19b5567004f858732cc4c12faec9b8be30442..af51fa9763681cc9728567f860c77534e9cc0c9d 100644 --- a/ecmascript/compiler/circuit_builder.h +++ b/ecmascript/compiler/circuit_builder.h @@ -231,7 +231,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); @@ -517,6 +516,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, MemoryOrder order = MemoryOrder::NOT_ATOMIC); GateRef LoadHClassFromConstpool(GateRef constpool, size_t index); diff --git a/ecmascript/compiler/gate_accessor.cpp b/ecmascript/compiler/gate_accessor.cpp index 9e62c17304df1a3d1b376e3d7a72a793869d676f..5c0006e0b6779a94c8d141a2d45b15087d53378d 100644 --- a/ecmascript/compiler/gate_accessor.cpp +++ b/ecmascript/compiler/gate_accessor.cpp @@ -157,8 +157,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 || GetOpCode(gate) == OpCode::LOAD_HCLASS_FROM_CONSTPOOL); Gate *gatePtr = circuit_->LoadGatePtr(gate); diff --git a/ecmascript/compiler/later_elimination.cpp b/ecmascript/compiler/later_elimination.cpp index f06ae402029bc5aa5e394c22233659554d4eaee9..49730d5fab6a3ce4714c3a306bfaf5379c9059be 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_circuit_builder.cpp b/ecmascript/compiler/mcr_circuit_builder.cpp index d0dd27b966a4314f27fab4cfd5969b22b6f9854a..67447e80eeb0b61cef205df06edb6eb42ea53f03 100644 --- a/ecmascript/compiler/mcr_circuit_builder.cpp +++ b/ecmascript/compiler/mcr_circuit_builder.cpp @@ -705,6 +705,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, MemoryOrder order) { auto currentLabel = env_->GetCurrentLabel(); diff --git a/ecmascript/compiler/mcr_lowering.cpp b/ecmascript/compiler/mcr_lowering.cpp index 971bb28306e9892c1ad6db492d6d3226882dbd6a..95719e010513163fda005a315e395baeeb1529d4 100644 --- a/ecmascript/compiler/mcr_lowering.cpp +++ b/ecmascript/compiler/mcr_lowering.cpp @@ -59,9 +59,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; @@ -675,18 +672,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 bd8d1ae9dc3062401b33c565ed0595539b27db96..bf8a17ac6d8f79133cf31e789482be3918d75f46 100644 --- a/ecmascript/compiler/mcr_lowering.h +++ b/ecmascript/compiler/mcr_lowering.h @@ -57,7 +57,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 88d7d3edddfa8ac3f37db006fe72978eb3b28d52..47ec4332b8118ccf3a30e838561f37d9dfad0af2 100644 --- a/ecmascript/compiler/mcr_opcodes.h +++ b/ecmascript/compiler/mcr_opcodes.h @@ -43,6 +43,8 @@ namespace panda::ecmascript::kungfu { V(LoadSetter, LOAD_SETTER, GateFlags::NO_WRITE, 1, 1, 3) \ 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) \ @@ -71,7 +73,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 eaab6542d9aaa15d33827f08d11a69ce02fbfcff..bc03a6f5e902e9824b9c46dfe45c6641c4d18dba 100644 --- a/ecmascript/compiler/ntype_hcr_lowering.cpp +++ b/ecmascript/compiler/ntype_hcr_lowering.cpp @@ -135,7 +135,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_bytecode_lowering.cpp b/ecmascript/compiler/type_bytecode_lowering.cpp index 9d68b9e4ec6740739c018735d425be952f2bf3f4..fd106b74072048b1fd7b457f2690ada646534fa2 100644 --- a/ecmascript/compiler/type_bytecode_lowering.cpp +++ b/ecmascript/compiler/type_bytecode_lowering.cpp @@ -1081,7 +1081,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); } @@ -1143,6 +1155,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) { AddProfiling(gate); diff --git a/ecmascript/compiler/type_bytecode_lowering.h b/ecmascript/compiler/type_bytecode_lowering.h index b40dafc4ecee5a1df7006e6198e432f8efc3e033..c37c22473b03d93df912b65207f08a4fb24ebae3 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 581d95eefa03813eeea17761a7dea362fd6c1a52..63cc43484f71c0850cff372af67042e1fcbb33d8 100644 --- a/ecmascript/compiler/type_hcr_lowering.cpp +++ b/ecmascript/compiler/type_hcr_lowering.cpp @@ -22,10 +22,13 @@ #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/js_object.h" #include "ecmascript/subtyping_operator.h" #include "ecmascript/vtable.h" -#include "ecmascript/message_string.h" namespace panda::ecmascript::kungfu { GateRef TypeHCRLowering::VisitGate(GateRef gate) { @@ -93,6 +96,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; @@ -318,7 +327,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); @@ -860,6 +871,28 @@ 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); + 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); + 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 4f59fa2c30af59f6af0426a01d632010514aa0c6..ad2dff29da7f7eabe008cf4e3d43305a5dfe989b 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 b15ca46752f316ce25fcbd51339181b6cd981c4f..9e387309a26376f06eed484e26d0723750bd2293 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") \