diff --git a/ecmascript/compiler/baseline/baseline_call_signature.cpp b/ecmascript/compiler/baseline/baseline_call_signature.cpp index 5ed64cb5e0..2bab262068 100644 --- a/ecmascript/compiler/baseline/baseline_call_signature.cpp +++ b/ecmascript/compiler/baseline/baseline_call_signature.cpp @@ -4165,6 +4165,38 @@ DEF_CALL_SIGNATURE(BaselineCallRuntimeLdSendableClassPrefImm16) BASELINE_STUB_CALL_SIGNATURE_COMMON_SET(); } +DEF_CALL_SIGNATURE(BaselineCallRuntimeIstruePrefImm8) +{ + // 4 : 4 input parameters + CallSignature signature("BaselineCallRuntimeIstruePrefImm8", 0, 4, + ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY()); + *callSign = signature; + // 4 : 4 input parameters + std::array params = { + VariableType::NATIVE_POINTER(), + VariableType::NATIVE_POINTER(), + VariableType::JS_ANY(), + VariableType::INT8(), + }; + BASELINE_STUB_CALL_SIGNATURE_COMMON_SET(); +} + +DEF_CALL_SIGNATURE(BaselineCallRuntimeIsfalsePrefImm8) +{ + // 4 : 4 input parameters + CallSignature signature("BaselineCallRuntimeIsfalsePrefImm8", 0, 4, + ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY()); + *callSign = signature; + // 4 : 4 input parameters + std::array params = { + VariableType::NATIVE_POINTER(), + VariableType::NATIVE_POINTER(), + VariableType::JS_ANY(), + VariableType::INT8(), + }; + BASELINE_STUB_CALL_SIGNATURE_COMMON_SET(); +} + // GLUE, ACC, SP DEF_CALL_SIGNATURE(BaselineReturnundefined) { diff --git a/ecmascript/compiler/baseline/baseline_call_signature.h b/ecmascript/compiler/baseline/baseline_call_signature.h index 453377ded6..39525d69d5 100644 --- a/ecmascript/compiler/baseline/baseline_call_signature.h +++ b/ecmascript/compiler/baseline/baseline_call_signature.h @@ -593,6 +593,10 @@ DEFINE_PARAMETER_INDEX(BaselineCallRuntimeDefineSendableClassPrefImm16Id16Id16Im GLUE, SP, METHOD_ID, LITERAL_ID, LENGTH, V0) DEFINE_PARAMETER_INDEX(BaselineCallRuntimeLdSendableClassPrefImm16, GLUE, SP, ACC, LEVEL) +DEFINE_PARAMETER_INDEX(BaselineCallRuntimeIstruePrefImm8, + GLUE, SP, ACC, V0) +DEFINE_PARAMETER_INDEX(BaselineCallRuntimeIsfalsePrefImm8, + GLUE, SP, ACC, V0) DEFINE_PARAMETER_INDEX(BaselineReturnundefined, GLUE, ACC, SP) DEFINE_PARAMETER_INDEX(BaselineExceptionHandler, GLUE, ACC, SP, PROFILE_TYPE_INFO, HOTNESS_COUNTER, FRAME) diff --git a/ecmascript/compiler/baseline/baseline_compiler.cpp b/ecmascript/compiler/baseline/baseline_compiler.cpp index b7eaab1843..f2beb9152d 100644 --- a/ecmascript/compiler/baseline/baseline_compiler.cpp +++ b/ecmascript/compiler/baseline/baseline_compiler.cpp @@ -3166,6 +3166,21 @@ BYTECODE_BASELINE_HANDLER_IMPLEMENT(ISTRUE) GetBaselineAssembler().SaveResultIntoAcc(); } +BYTECODE_BASELINE_HANDLER_IMPLEMENT(CALLRUNTIME_ISTRUE_PREF_IMM8) +{ + (void)bytecodeArray; + + auto *thread = vm->GetAssociatedJSThread(); + Address builtinAddress = + thread->GetBaselineStubEntry(BaselineStubCSigns::BaselineCallRuntimeIstruePrefImm8); + LOG_INST() << " BaselineCallRuntimeIstruePrefImm8 Address: " << std::hex << builtinAddress; + + std::vector parameters; + parameters.emplace_back(BaselineSpecialParameter::ACC); + GetBaselineAssembler().CallBuiltin(builtinAddress, parameters); + GetBaselineAssembler().SaveResultIntoAcc(); +} + BYTECODE_BASELINE_HANDLER_IMPLEMENT(ISFALSE) { (void)bytecodeArray; @@ -3180,6 +3195,22 @@ BYTECODE_BASELINE_HANDLER_IMPLEMENT(ISFALSE) GetBaselineAssembler().CallBuiltin(builtinAddress, parameters); GetBaselineAssembler().SaveResultIntoAcc(); } + +BYTECODE_BASELINE_HANDLER_IMPLEMENT(CALLRUNTIME_ISFALSE_PREF_IMM8) +{ + (void)bytecodeArray; + + auto *thread = vm->GetAssociatedJSThread(); + Address builtinAddress = + thread->GetBaselineStubEntry(BaselineStubCSigns::BaselineCallRuntimeIsfalsePrefImm8); + LOG_INST() << " BaselineCallRuntimeIsfalsePrefImm8 Address: " << std::hex << builtinAddress; + + std::vector parameters; + parameters.emplace_back(BaselineSpecialParameter::ACC); + GetBaselineAssembler().CallBuiltin(builtinAddress, parameters); + GetBaselineAssembler().SaveResultIntoAcc(); +} + // ------- End parse bytecodes about comparison ------- // ------- parse bytecodes about control flow ------- diff --git a/ecmascript/compiler/baseline/baseline_compiler_builtins.h b/ecmascript/compiler/baseline/baseline_compiler_builtins.h index c91813591a..df57fa122d 100644 --- a/ecmascript/compiler/baseline/baseline_compiler_builtins.h +++ b/ecmascript/compiler/baseline/baseline_compiler_builtins.h @@ -282,6 +282,8 @@ namespace panda::ecmascript::kungfu { V(BaselineCallRuntimeCallInitPrefImm8V8) \ V(BaselineCallRuntimeDefineSendableClassPrefImm16Id16Id16Imm16V8) \ V(BaselineCallRuntimeLdSendableClassPrefImm16) \ + V(BaselineCallRuntimeIstruePrefImm8) \ + V(BaselineCallRuntimeIsfalsePrefImm8) \ V(BaselineReturnundefined) \ V(BaselineExceptionHandler) \ V(BaselineUpdateHotness) \ diff --git a/ecmascript/compiler/baseline/baseline_stubs.cpp b/ecmascript/compiler/baseline/baseline_stubs.cpp index f9b4cea29a..8dc4c8448e 100644 --- a/ecmascript/compiler/baseline/baseline_stubs.cpp +++ b/ecmascript/compiler/baseline/baseline_stubs.cpp @@ -1181,6 +1181,15 @@ void BaselineIstrueStubBuilder::GenerateCircuit() Return(*varAcc); } +void BaselineCallRuntimeIstruePrefImm8StubBuilder::GenerateCircuit() +{ + GateRef acc = TaggedArgument(PARAM_INDEX(BaselineCallRuntimeIstruePrefImm8, ACC)); + + DEFVARIABLE(varAcc, VariableType::JS_ANY(), acc); + varAcc = FastToBooleanBaseline(*varAcc, true); + Return(*varAcc); +} + void BaselineIsfalseStubBuilder::GenerateCircuit() { GateRef acc = TaggedArgument(PARAM_INDEX(BaselineIsfalse, ACC)); @@ -1190,6 +1199,16 @@ void BaselineIsfalseStubBuilder::GenerateCircuit() Return(*varAcc); } +void BaselineCallRuntimeIsfalsePrefImm8StubBuilder::GenerateCircuit() +{ + GateRef acc = TaggedArgument(PARAM_INDEX(BaselineCallRuntimeIsfalsePrefImm8, ACC)); + + DEFVARIABLE(varAcc, VariableType::JS_ANY(), acc); + varAcc = FastToBooleanBaseline(*varAcc, false); + Return(*varAcc); +} + + void BaselineCallthis3Imm8V8V8V8V8StubBuilder::GenerateCircuit() { GateRef glue = PtrArgument(PARAM_INDEX(BaselineCallthis3Imm8V8V8V8V8, GLUE)); diff --git a/ecmascript/compiler/bc_call_signature.h b/ecmascript/compiler/bc_call_signature.h index ff1a123438..23d970d0d2 100644 --- a/ecmascript/compiler/bc_call_signature.h +++ b/ecmascript/compiler/bc_call_signature.h @@ -390,7 +390,9 @@ namespace panda::ecmascript::kungfu { T(HandleCallRuntimeStSendableVarImm16Imm16) \ T(HandleCallRuntimeLdSendableVarImm4Imm4) \ T(HandleCallRuntimeLdSendableVarImm8Imm8) \ - T(HandleCallRuntimeLdSendableVarImm16Imm16) + T(HandleCallRuntimeLdSendableVarImm16Imm16) \ + T(HandleCallRuntimeIstruePrefImm8) \ + T(HandleCallRuntimeIsfalsePrefImm8) #define ASM_INTERPRETER_BC_HELPER_STUB_LIST(V) \ V(SingleStepDebugging) \ @@ -465,7 +467,9 @@ namespace panda::ecmascript::kungfu { APPEND_SUFFIX(HandleGreatereqImm8V8, V) \ APPEND_SUFFIX(HandleStrictnoteqImm8V8, V) \ APPEND_SUFFIX(HandleStricteqImm8V8, V) \ - APPEND_SUFFIX(HandleTonumericImm8, V) + APPEND_SUFFIX(HandleTonumericImm8, V) \ + APPEND_SUFFIX_IMM8_SECONDBC(HandleCallRuntimeIstruePrefImm8, V) \ + APPEND_SUFFIX_IMM8_SECONDBC(HandleCallRuntimeIsfalsePrefImm8, V) \ #define ASM_INTERPRETER_BC_FUNC_HOT_PROFILER_STUB_LIST(V) \ APPEND_SUFFIX(HandleJmpImm8, V) \ diff --git a/ecmascript/compiler/bytecodes.cpp b/ecmascript/compiler/bytecodes.cpp index f610adc9d3..c3e46147c8 100644 --- a/ecmascript/compiler/bytecodes.cpp +++ b/ecmascript/compiler/bytecodes.cpp @@ -42,6 +42,8 @@ BytecodeMetaData BytecodeMetaData::InitBytecodeMetaData(const uint8_t *pc) case EcmaOpcode::WIDE_GETMODULENAMESPACE_PREF_IMM16: case EcmaOpcode::ISTRUE: case EcmaOpcode::ISFALSE: + case EcmaOpcode::CALLRUNTIME_ISTRUE_PREF_IMM8: + case EcmaOpcode::CALLRUNTIME_ISFALSE_PREF_IMM8: case EcmaOpcode::LDGLOBALVAR_IMM16_ID16: case EcmaOpcode::LDOBJBYINDEX_IMM8_IMM16: case EcmaOpcode::LDOBJBYINDEX_IMM16_IMM16: @@ -122,6 +124,8 @@ BytecodeMetaData BytecodeMetaData::InitBytecodeMetaData(const uint8_t *pc) case EcmaOpcode::TYPEOF_IMM16: case EcmaOpcode::ISTRUE: case EcmaOpcode::ISFALSE: + case EcmaOpcode::CALLRUNTIME_ISTRUE_PREF_IMM8: + case EcmaOpcode::CALLRUNTIME_ISFALSE_PREF_IMM8: case EcmaOpcode::JEQZ_IMM8: case EcmaOpcode::JEQZ_IMM16: case EcmaOpcode::JEQZ_IMM32: @@ -231,6 +235,8 @@ BytecodeMetaData BytecodeMetaData::InitBytecodeMetaData(const uint8_t *pc) case EcmaOpcode::TONUMERIC_IMM8: case EcmaOpcode::ISTRUE: case EcmaOpcode::ISFALSE: + case EcmaOpcode::CALLRUNTIME_ISTRUE_PREF_IMM8: + case EcmaOpcode::CALLRUNTIME_ISFALSE_PREF_IMM8: case EcmaOpcode::INC_IMM8: case EcmaOpcode::DEC_IMM8: case EcmaOpcode::NEG_IMM8: @@ -1829,6 +1835,8 @@ void BytecodeInfo::InitBytecodeInfo(BytecodeCircuitBuilder *builder, case EcmaOpcode::DEBUGGER: case EcmaOpcode::ISTRUE: case EcmaOpcode::ISFALSE: + case EcmaOpcode::CALLRUNTIME_ISTRUE_PREF_IMM8: + case EcmaOpcode::CALLRUNTIME_ISFALSE_PREF_IMM8: case EcmaOpcode::NOP: case EcmaOpcode::GETITERATOR_IMM8: case EcmaOpcode::GETITERATOR_IMM16: diff --git a/ecmascript/compiler/bytecodes.h b/ecmascript/compiler/bytecodes.h index b12d002fa9..ccb0341f25 100644 --- a/ecmascript/compiler/bytecodes.h +++ b/ecmascript/compiler/bytecodes.h @@ -282,7 +282,7 @@ public: static constexpr uint32_t LAST_THROW_OPCODE = static_cast(EcmaOpcode::THROW_UNDEFINEDIFHOLEWITHNAME_PREF_ID16); static constexpr uint32_t LAST_CALLRUNTIME_OPCODE = - static_cast(EcmaOpcode::CALLRUNTIME_WIDELDSENDABLEVAR_PREF_IMM16_IMM16); + static_cast(EcmaOpcode::CALLRUNTIME_ISFALSE_PREF_IMM8); static_assert(CALLRUNTIME_PREFIX_OPCODE_INDEX == static_cast(EcmaOpcode::CALLRUNTIME_NOTIFYCONCURRENTRESULT_PREF_NONE)); diff --git a/ecmascript/compiler/ecma_opcode_des.h b/ecmascript/compiler/ecma_opcode_des.h index cb8608c2c5..aa6b4cf1ec 100644 --- a/ecmascript/compiler/ecma_opcode_des.h +++ b/ecmascript/compiler/ecma_opcode_des.h @@ -338,6 +338,8 @@ namespace panda::ecmascript::kungfu { V(CALLRUNTIME_LDSENDABLEVAR_PREF_IMM4_IMM4) \ V(CALLRUNTIME_LDSENDABLEVAR_PREF_IMM8_IMM8) \ V(CALLRUNTIME_WIDELDSENDABLEVAR_PREF_IMM16_IMM16) \ + V(CALLRUNTIME_ISTRUE_PREF_IMM8) \ + V(CALLRUNTIME_ISFALSE_PREF_IMM8) \ inline std::string GetEcmaOpcodeStr(EcmaOpcode opcode) { diff --git a/ecmascript/compiler/interpreter_stub.cpp b/ecmascript/compiler/interpreter_stub.cpp index a9aaa176a7..fc35e8b3e5 100644 --- a/ecmascript/compiler/interpreter_stub.cpp +++ b/ecmascript/compiler/interpreter_stub.cpp @@ -3130,6 +3130,13 @@ DECLARE_ASM_HANDLER(HandleIstrue) DISPATCH_WITH_ACC(ISTRUE); } +DECLARE_ASM_HANDLER(HandleCallRuntimeIstruePrefImm8) +{ + DEFVARIABLE(varAcc, VariableType::JS_ANY(), acc); + varAcc = FastToBooleanWithProfile(*varAcc, callback, true); + DISPATCH_WITH_ACC(CALLRUNTIME_ISTRUE_PREF_IMM8); +} + DECLARE_ASM_HANDLER(HandleIsfalse) { DEFVARIABLE(varAcc, VariableType::JS_ANY(), acc); @@ -3137,6 +3144,13 @@ DECLARE_ASM_HANDLER(HandleIsfalse) DISPATCH_WITH_ACC(ISFALSE); } +DECLARE_ASM_HANDLER(HandleCallRuntimeIsfalsePrefImm8) +{ + DEFVARIABLE(varAcc, VariableType::JS_ANY(), acc); + varAcc = FastToBooleanWithProfile(*varAcc, callback, false); + DISPATCH_WITH_ACC(CALLRUNTIME_ISFALSE_PREF_IMM8); +} + DECLARE_ASM_HANDLER(HandleTonumberImm8) { auto env = GetEnvironment(); diff --git a/ecmascript/compiler/slowpath_lowering.cpp b/ecmascript/compiler/slowpath_lowering.cpp index 17fe152253..cff4cecce8 100644 --- a/ecmascript/compiler/slowpath_lowering.cpp +++ b/ecmascript/compiler/slowpath_lowering.cpp @@ -510,9 +510,11 @@ void SlowPathLowering::Lower(GateRef gate) LowerSuperCallSpread(gate); break; case EcmaOpcode::ISTRUE: + case EcmaOpcode::CALLRUNTIME_ISTRUE_PREF_IMM8: LowerIsTrueOrFalse(gate, true); break; case EcmaOpcode::ISFALSE: + case EcmaOpcode::CALLRUNTIME_ISFALSE_PREF_IMM8: LowerIsTrueOrFalse(gate, false); break; case EcmaOpcode::GETNEXTPROPNAME_V8: diff --git a/ecmascript/compiler/stub_builder.cpp b/ecmascript/compiler/stub_builder.cpp index 0142324675..84772771a7 100644 --- a/ecmascript/compiler/stub_builder.cpp +++ b/ecmascript/compiler/stub_builder.cpp @@ -5903,6 +5903,126 @@ GateRef StubBuilder::FastToBooleanBaseline(GateRef value, bool flag) return ret; } +GateRef StubBuilder::FastToBooleanWithProfile(GateRef value, ProfileOperation callback, bool flag) +{ + auto env = GetEnvironment(); + Label entry(env); + env->SubCfgEntry(&entry); + DEFVARIABLE(result, VariableType::JS_ANY(), Hole()); + Label exit(env); + + Label isSpecial(env); + Label notSpecial(env); + Label isNumber(env); + Label isInt(env); + Label isDouble(env); + Label notNumber(env); + Label notNan(env); + Label isString(env); + Label notString(env); + Label isBigint(env); + Label lengthIsOne(env); + Label returnTrue(env); + Label returnFalse(env); + Label isTrue(env); + Label isNotTrue(env); + Label isFalse(env); + Label isNotFalse(env); + + BRANCH(TaggedIsSpecial(value), &isSpecial, ¬Special); + Bind(&isSpecial); + { + BRANCH(TaggedIsTrue(value), &isTrue, &isNotTrue); + Bind(&isTrue); + { + callback.ProfileOpType(Int32(PGOSampleType::BooleanType())); + Jump(&returnTrue); + } + Bind(&isNotTrue); + { + BRANCH(TaggedIsFalse(value), &isFalse, &isNotFalse); + Bind(&isFalse); + { + callback.ProfileOpType(Int32(PGOSampleType::BooleanType())); + Jump(&returnFalse); + } + } + Bind(&isNotFalse); + Jump(&returnFalse); + } + Bind(¬Special); + { + BRANCH(TaggedIsNumber(value), &isNumber, ¬Number); + Bind(¬Number); + { + BRANCH(IsString(value), &isString, ¬String); + Bind(&isString); + { + auto len = GetLengthFromString(value); + BRANCH(Int32Equal(len, Int32(0)), &returnFalse, &returnTrue); + } + Bind(¬String); + BRANCH(TaggedObjectIsBigInt(value), &isBigint, &returnTrue); + Bind(&isBigint); + { + auto len = Load(VariableType::INT32(), value, IntPtr(BigInt::LENGTH_OFFSET)); + BRANCH(Int32Equal(len, Int32(1)), &lengthIsOne, &returnTrue); + Bind(&lengthIsOne); + { + auto data = PtrAdd(value, IntPtr(BigInt::DATA_OFFSET)); + auto data0 = Load(VariableType::INT32(), data, Int32(0)); + BRANCH(Int32Equal(data0, Int32(0)), &returnFalse, &returnTrue); + } + } + } + Bind(&isNumber); + { + callback.ProfileOpType(Int32(PGOSampleType::NumberType())); + BRANCH(TaggedIsInt(value), &isInt, &isDouble); + Bind(&isInt); + { + auto intValue = GetInt32OfTInt(value); + BRANCH(Int32Equal(intValue, Int32(0)), &returnFalse, &returnTrue); + } + Bind(&isDouble); + { + auto doubleValue = GetDoubleOfTDouble(value); + BRANCH(DoubleIsNAN(doubleValue), &returnFalse, ¬Nan); + Bind(¬Nan); + BRANCH(DoubleEqual(doubleValue, Double(0.0)), &returnFalse, &returnTrue); + } + } + } + if (flag == 1) { + Bind(&returnTrue); + { + result = TaggedTrue(); + Jump(&exit); + } + Bind(&returnFalse); + { + result = TaggedFalse(); + Jump(&exit); + } + } else { + Bind(&returnFalse); + { + result = TaggedTrue(); + Jump(&exit); + } + Bind(&returnTrue); + { + result = TaggedFalse(); + Jump(&exit); + } + } + + Bind(&exit); + auto ret = *result; + env->SubCfgExit(); + return ret; +} + GateRef StubBuilder::FastDiv(GateRef left, GateRef right, ProfileOperation callback) { auto env = GetEnvironment(); diff --git a/ecmascript/compiler/stub_builder.h b/ecmascript/compiler/stub_builder.h index 7af2291553..4cbead132c 100644 --- a/ecmascript/compiler/stub_builder.h +++ b/ecmascript/compiler/stub_builder.h @@ -736,6 +736,7 @@ public: GateRef FastSub(GateRef glue, GateRef left, GateRef right, ProfileOperation callback); GateRef FastToBoolean(GateRef value, bool flag = true); GateRef FastToBooleanBaseline(GateRef value, bool flag = true); + GateRef FastToBooleanWithProfile(GateRef value, ProfileOperation callback, bool flag = true); // Add SpecialContainer GateRef GetContainerProperty(GateRef glue, GateRef receiver, GateRef index, GateRef jsType); diff --git a/ecmascript/compiler/typed_bytecode_lowering.cpp b/ecmascript/compiler/typed_bytecode_lowering.cpp index 966cb9e128..68ba1fc270 100644 --- a/ecmascript/compiler/typed_bytecode_lowering.cpp +++ b/ecmascript/compiler/typed_bytecode_lowering.cpp @@ -229,9 +229,11 @@ void TypedBytecodeLowering::Lower(GateRef gate) LowerTypedEqOrNotEq(gate); break; case EcmaOpcode::ISTRUE: + case EcmaOpcode::CALLRUNTIME_ISTRUE_PREF_IMM8: LowerTypedIsTrueOrFalse(gate, true); break; case EcmaOpcode::ISFALSE: + case EcmaOpcode::CALLRUNTIME_ISFALSE_PREF_IMM8: LowerTypedIsTrueOrFalse(gate, false); break; case EcmaOpcode::CALLTHIS3_IMM8_V8_V8_V8_V8: @@ -1366,13 +1368,22 @@ void TypedBytecodeLowering::LowerTypedStObjByValue(GateRef gate) } } +bool TypedBytecodeLowering::IsTrueOrFalseHasProfileType(GateRef gate) const +{ + ASSERT(acc_.GetOpCode(gate) == OpCode::JS_BYTECODE); + return acc_.GetByteCodeOpcode(gate) == EcmaOpcode::CALLRUNTIME_ISTRUE_PREF_IMM8 || + acc_.GetByteCodeOpcode(gate) == EcmaOpcode::CALLRUNTIME_ISFALSE_PREF_IMM8; +} + void TypedBytecodeLowering::LowerTypedIsTrueOrFalse(GateRef gate, bool flag) { UnOpTypeInfoAccessor tacc(compilationEnv_, circuit_, gate); ParamType paramType; - if (TypeInfoAccessor::IsTrustedBooleanType(acc_, tacc.GetValue())) { + if (TypeInfoAccessor::IsTrustedBooleanType(acc_, tacc.GetValue()) || + (IsTrueOrFalseHasProfileType(gate) && tacc.IsBooleanType())) { paramType = ParamType::BooleanType(); - } else if (TypeInfoAccessor::IsTrustedNumberType(acc_, tacc.GetValue())) { + } else if (TypeInfoAccessor::IsTrustedNumberType(acc_, tacc.GetValue()) || + (IsTrueOrFalseHasProfileType(gate) && tacc.HasNumberType())) { paramType = ParamType::NumberType(); } else { return; diff --git a/ecmascript/compiler/typed_bytecode_lowering.h b/ecmascript/compiler/typed_bytecode_lowering.h index f5cc39bf3f..15305c1d23 100644 --- a/ecmascript/compiler/typed_bytecode_lowering.h +++ b/ecmascript/compiler/typed_bytecode_lowering.h @@ -215,6 +215,7 @@ private: bool TryLowerNewBuiltinConstructor(GateRef gate); bool TryLowerTypedLdobjBynameFromGloablBuiltin(GateRef gate); bool CheckIsInOptBCIgnoreRange(int32_t index, EcmaOpcode ecmaOpcode); + bool IsTrueOrFalseHasProfileType(GateRef gate) const; int32_t GetEcmaOpCodeListIndex(EcmaOpcode ecmaOpCode); void ParseOptBytecodeRange(); diff --git a/ecmascript/interpreter/interpreter-inl.cpp b/ecmascript/interpreter/interpreter-inl.cpp index 6a00ba69a4..bd8e9f2269 100644 --- a/ecmascript/interpreter/interpreter-inl.cpp +++ b/ecmascript/interpreter/interpreter-inl.cpp @@ -1019,7 +1019,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t constexpr size_t numOps = 0x100; constexpr size_t numThrowOps = 10; constexpr size_t numWideOps = 20; - constexpr size_t numCallRuntimeOps = 19; + constexpr size_t numCallRuntimeOps = 21; constexpr size_t numDeprecatedOps = 47; static std::array instDispatchTable { @@ -3817,6 +3817,15 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t } DISPATCH(ISTRUE); } + HANDLE_OPCODE(CALLRUNTIME_ISTRUE_PREF_IMM8) { + LOG_INST() << "intrinsics::callruntime.istrue"; + if (GET_ACC().ToBoolean()) { + SET_ACC(JSTaggedValue::True()); + } else { + SET_ACC(JSTaggedValue::False()); + } + DISPATCH(CALLRUNTIME_ISTRUE_PREF_IMM8); + } HANDLE_OPCODE(ISFALSE) { LOG_INST() << "intrinsics::isfalse"; if (!GET_ACC().ToBoolean()) { @@ -3826,6 +3835,15 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t } DISPATCH(ISFALSE); } + HANDLE_OPCODE(CALLRUNTIME_ISFALSE_PREF_IMM8) { + LOG_INST() << "intrinsics::callruntime.isfalse"; + if (!GET_ACC().ToBoolean()) { + SET_ACC(JSTaggedValue::True()); + } else { + SET_ACC(JSTaggedValue::False()); + } + DISPATCH(CALLRUNTIME_ISFALSE_PREF_IMM8); + } NOPRINT_HANDLE_OPCODE(EXCEPTION) { FrameHandler frameHandler(thread); uint32_t pcOffset = panda_file::INVALID_OFFSET; diff --git a/ecmascript/interpreter/interpreter_assembly.cpp b/ecmascript/interpreter/interpreter_assembly.cpp index a6c6521d9d..7c13db8b4d 100644 --- a/ecmascript/interpreter/interpreter_assembly.cpp +++ b/ecmascript/interpreter/interpreter_assembly.cpp @@ -2960,19 +2960,45 @@ void InterpreterAssembly::HandleIstrue( DISPATCH(ISTRUE); } +void InterpreterAssembly::HandleCallRuntimeIstruePrefImm8( + JSThread *thread, const uint8_t *pc, JSTaggedType *sp, JSTaggedValue constpool, JSTaggedValue profileTypeInfo, + JSTaggedValue acc, int16_t hotnessCounter) +{ + LOG_INST() << "intrinsics::callruntimeistrueprefimm8"; + if (GET_ACC().ToBoolean()) { + SET_ACC(JSTaggedValue::True()); + } else { + SET_ACC(JSTaggedValue::False()); + } + DISPATCH(CALLRUNTIME_ISTRUE_PREF_IMM8); +} + void InterpreterAssembly::HandleIsfalse( JSThread *thread, const uint8_t *pc, JSTaggedType *sp, JSTaggedValue constpool, JSTaggedValue profileTypeInfo, JSTaggedValue acc, int16_t hotnessCounter) { LOG_INST() << "intrinsics::isfalse"; - if (!GET_ACC().ToBoolean()) { - SET_ACC(JSTaggedValue::True()); - } else { + if (GET_ACC().ToBoolean()) { SET_ACC(JSTaggedValue::False()); + } else { + SET_ACC(JSTaggedValue::True()); } DISPATCH(ISFALSE); } +void InterpreterAssembly::HandleCallRuntimeIsfalsePrefImm8( + JSThread *thread, const uint8_t *pc, JSTaggedType *sp, JSTaggedValue constpool, JSTaggedValue profileTypeInfo, + JSTaggedValue acc, int16_t hotnessCounter) +{ + LOG_INST() << "intrinsics::callruntimeisfalseprefimm8"; + if (GET_ACC().ToBoolean()) { + SET_ACC(JSTaggedValue::False()); + } else { + SET_ACC(JSTaggedValue::True()); + } + DISPATCH(CALLRUNTIME_ISFALSE_PREF_IMM8); +} + void InterpreterAssembly::HandleTypeofImm16( JSThread *thread, const uint8_t *pc, JSTaggedType *sp, JSTaggedValue constpool, JSTaggedValue profileTypeInfo, JSTaggedValue acc, int16_t hotnessCounter) diff --git a/ecmascript/interpreter/templates/call_runtime_instruction_dispatch.inl b/ecmascript/interpreter/templates/call_runtime_instruction_dispatch.inl index 34d3a26c7c..2bbec51a2e 100755 --- a/ecmascript/interpreter/templates/call_runtime_instruction_dispatch.inl +++ b/ecmascript/interpreter/templates/call_runtime_instruction_dispatch.inl @@ -31,4 +31,6 @@ &&HANDLE_CALLRUNTIME_WIDESTSENDABLEVAR_PREF_IMM16_IMM16, &&HANDLE_CALLRUNTIME_LDSENDABLEVAR_PREF_IMM4_IMM4, &&HANDLE_CALLRUNTIME_LDSENDABLEVAR_PREF_IMM8_IMM8, - &&HANDLE_CALLRUNTIME_WIDELDSENDABLEVAR_PREF_IMM16_IMM16, \ No newline at end of file + &&HANDLE_CALLRUNTIME_WIDELDSENDABLEVAR_PREF_IMM16_IMM16, + &&HANDLE_CALLRUNTIME_ISTRUE_PREF_IMM8, + &&HANDLE_CALLRUNTIME_ISFALSE_PREF_IMM8, diff --git a/ecmascript/pgo_profiler/pgo_profiler.cpp b/ecmascript/pgo_profiler/pgo_profiler.cpp index b0e48f3ce2..f753b38f00 100644 --- a/ecmascript/pgo_profiler/pgo_profiler.cpp +++ b/ecmascript/pgo_profiler/pgo_profiler.cpp @@ -698,6 +698,13 @@ void PGOProfiler::ProfileBytecode(ApEntityId abcId, const CString &recordName, J DumpOpType(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo); break; } + case EcmaOpcode::CALLRUNTIME_ISTRUE_PREF_IMM8: + case EcmaOpcode::CALLRUNTIME_ISFALSE_PREF_IMM8: { + uint8_t slotId = READ_INST_8_1(); + CHECK_SLOTID_BREAK(slotId); + DumpOpType(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo); + break; + } // Call case EcmaOpcode::CALLARG0_IMM8: case EcmaOpcode::CALLARG1_IMM8_V8: diff --git a/test/aottest/definefieldbyname/definefieldbyname.js b/test/aottest/definefieldbyname/definefieldbyname.js index 414b718127..96dee7410c 100644 --- a/test/aottest/definefieldbyname/definefieldbyname.js +++ b/test/aottest/definefieldbyname/definefieldbyname.js @@ -28,6 +28,7 @@ const b = new B(); print(b.x); -for (let i = 0; i < 400; i ++){ +for (let i = 0; i < 400; i++){ + // warm up profile type info } print(new B().x);