mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Update Value constructors
Improve Value::Value(double) performance. Add missing double and int32 type testing on interpreter Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
parent
ebd5a42641
commit
3631ae6097
4 changed files with 62 additions and 37 deletions
|
|
@ -65,7 +65,7 @@ Value builtinArrayConstructor(ExecutionState& state, Value thisValue, size_t arg
|
|||
|
||||
if (interpretArgumentsAsElements) {
|
||||
Value val = argv[0];
|
||||
if (argc > 1 || !val.isInt32()) {
|
||||
if (argc > 1 || !val.isNumber()) {
|
||||
if (array->isFastModeArray()) {
|
||||
for (size_t idx = 0; idx < argc; idx++) {
|
||||
array->m_fastModeData[idx] = argv[idx];
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ Value ByteCodeInterpreter::interpret(ExecutionState* state, ByteCodeBlock* byteC
|
|||
BinaryPlus* code = (BinaryPlus*)programCounter;
|
||||
const Value& v0 = registerFile[code->m_srcIndex0];
|
||||
const Value& v1 = registerFile[code->m_srcIndex1];
|
||||
Value ret(Value::ForceUninitialized);
|
||||
Value& ret = registerFile[code->m_dstIndex];
|
||||
if (v0.isInt32() && v1.isInt32()) {
|
||||
int32_t a = v0.asInt32();
|
||||
int32_t b = v1.asInt32();
|
||||
|
|
@ -262,7 +262,6 @@ Value ByteCodeInterpreter::interpret(ExecutionState* state, ByteCodeBlock* byteC
|
|||
} else {
|
||||
ret = plusSlowCase(*state, v0, v1);
|
||||
}
|
||||
registerFile[code->m_dstIndex] = ret;
|
||||
ADD_PROGRAM_COUNTER(BinaryPlus);
|
||||
NEXT_INSTRUCTION();
|
||||
}
|
||||
|
|
@ -273,7 +272,7 @@ Value ByteCodeInterpreter::interpret(ExecutionState* state, ByteCodeBlock* byteC
|
|||
BinaryMinus* code = (BinaryMinus*)programCounter;
|
||||
const Value& left = registerFile[code->m_srcIndex0];
|
||||
const Value& right = registerFile[code->m_srcIndex1];
|
||||
Value ret(Value::ForceUninitialized);
|
||||
Value& ret = registerFile[code->m_dstIndex];
|
||||
if (left.isInt32() && right.isInt32()) {
|
||||
int32_t a = left.asInt32();
|
||||
int32_t b = right.asInt32();
|
||||
|
|
@ -289,7 +288,6 @@ Value ByteCodeInterpreter::interpret(ExecutionState* state, ByteCodeBlock* byteC
|
|||
} else {
|
||||
ret = minusSlowCase(*state, left, right);
|
||||
}
|
||||
registerFile[code->m_dstIndex] = ret;
|
||||
ADD_PROGRAM_COUNTER(BinaryMinus);
|
||||
NEXT_INSTRUCTION();
|
||||
}
|
||||
|
|
@ -300,7 +298,7 @@ Value ByteCodeInterpreter::interpret(ExecutionState* state, ByteCodeBlock* byteC
|
|||
BinaryMultiply* code = (BinaryMultiply*)programCounter;
|
||||
const Value& left = registerFile[code->m_srcIndex0];
|
||||
const Value& right = registerFile[code->m_srcIndex1];
|
||||
Value ret(Value::ForceUninitialized);
|
||||
Value& ret = registerFile[code->m_dstIndex];
|
||||
if (left.isInt32() && right.isInt32()) {
|
||||
int32_t a = left.asInt32();
|
||||
int32_t b = right.asInt32();
|
||||
|
|
@ -316,11 +314,10 @@ Value ByteCodeInterpreter::interpret(ExecutionState* state, ByteCodeBlock* byteC
|
|||
}
|
||||
}
|
||||
} else if (LIKELY(left.isNumber() && right.isNumber())) {
|
||||
ret = Value(Value::EncodeAsDouble, left.asNumber() * right.asNumber());
|
||||
ret = Value(left.asNumber() * right.asNumber());
|
||||
} else {
|
||||
ret = multiplySlowCase(*state, left, right);
|
||||
}
|
||||
registerFile[code->m_dstIndex] = ret;
|
||||
ADD_PROGRAM_COUNTER(BinaryMultiply);
|
||||
NEXT_INSTRUCTION();
|
||||
}
|
||||
|
|
@ -331,10 +328,11 @@ Value ByteCodeInterpreter::interpret(ExecutionState* state, ByteCodeBlock* byteC
|
|||
BinaryDivision* code = (BinaryDivision*)programCounter;
|
||||
const Value& left = registerFile[code->m_srcIndex0];
|
||||
const Value& right = registerFile[code->m_srcIndex1];
|
||||
Value& ret = registerFile[code->m_dstIndex];
|
||||
if (LIKELY(left.isNumber() && right.isNumber())) {
|
||||
registerFile[code->m_dstIndex] = Value(left.asNumber() / right.asNumber());
|
||||
ret = Value(left.asNumber() / right.asNumber());
|
||||
} else {
|
||||
registerFile[code->m_dstIndex] = divisionSlowCase(*state, left, right);
|
||||
ret = divisionSlowCase(*state, left, right);
|
||||
}
|
||||
ADD_PROGRAM_COUNTER(BinaryDivision);
|
||||
NEXT_INSTRUCTION();
|
||||
|
|
@ -1633,7 +1631,7 @@ NEVER_INLINE Value ByteCodeInterpreter::multiplySlowCase(ExecutionState& state,
|
|||
if (UNLIKELY(lnum.second)) {
|
||||
return Value(lnum.first.asBigInt()->multiply(state, rnum.first.asBigInt()));
|
||||
} else {
|
||||
return Value(Value::EncodeAsDouble, lnum.first.asNumber() * rnum.first.asNumber());
|
||||
return Value(lnum.first.asNumber() * rnum.first.asNumber());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1650,7 +1648,7 @@ NEVER_INLINE Value ByteCodeInterpreter::divisionSlowCase(ExecutionState& state,
|
|||
}
|
||||
return Value(lnum.first.asBigInt()->division(state, rnum.first.asBigInt()));
|
||||
} else {
|
||||
return Value(Value::EncodeAsDouble, lnum.first.asNumber() / rnum.first.asNumber());
|
||||
return Value(lnum.first.asNumber() / rnum.first.asNumber());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -143,8 +143,8 @@ public:
|
|||
#endif
|
||||
|
||||
// Numbers
|
||||
Value(EncodeAsDoubleTag, double);
|
||||
explicit Value(double);
|
||||
Value(EncodeAsDoubleTag, const double&);
|
||||
explicit Value(const double&);
|
||||
explicit Value(bool);
|
||||
explicit Value(char);
|
||||
explicit Value(unsigned char);
|
||||
|
|
@ -274,6 +274,9 @@ public:
|
|||
intptr_t payload() const;
|
||||
static constexpr double maximumLength();
|
||||
|
||||
static bool isInt32ConvertibleDouble(const double& d);
|
||||
static bool isInt32ConvertibleDouble(const double& d, int32_t& asInt32);
|
||||
|
||||
private:
|
||||
ValueDescriptor u;
|
||||
double toNumberSlowCase(ExecutionState& ec) const; // $7.1.3 ToNumber
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ inline Value::Value(FromTagTag, uint32_t tag)
|
|||
u.asBits.payload = 0;
|
||||
}
|
||||
|
||||
inline Value::Value(EncodeAsDoubleTag, double d)
|
||||
inline Value::Value(EncodeAsDoubleTag, const double& d)
|
||||
{
|
||||
u.asDouble = d;
|
||||
}
|
||||
|
|
@ -412,7 +412,7 @@ inline double reinterpretInt64ToDouble(int64_t value)
|
|||
return bitwise_cast<double>(value);
|
||||
}
|
||||
|
||||
inline Value::Value(EncodeAsDoubleTag, double d)
|
||||
inline Value::Value(EncodeAsDoubleTag, const double& d)
|
||||
{
|
||||
u.asInt64 = reinterpretDoubleToInt64(d) + DoubleEncodeOffset;
|
||||
}
|
||||
|
|
@ -589,19 +589,38 @@ inline intptr_t Value::payload() const
|
|||
// ===common architecture========================================================
|
||||
// ==============================================================================
|
||||
|
||||
inline Value::Value(double d)
|
||||
ALWAYS_INLINE bool Value::isInt32ConvertibleDouble(const double& d)
|
||||
{
|
||||
const int32_t asInt32 = static_cast<int32_t>(d);
|
||||
if (asInt32 != d || (!asInt32 && std::signbit(d))) { // true for -0.0
|
||||
#ifdef ESCARGOT_64
|
||||
if (UNLIKELY((bitwise_cast<int64_t>(d) & DoubleInvalidBeginning) == DoubleInvalidBeginning)) {
|
||||
d = std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
#endif
|
||||
*this = Value(EncodeAsDouble, d);
|
||||
int32_t asInt32 = static_cast<int32_t>(d);
|
||||
if (LIKELY(LIKELY(asInt32 != d) || UNLIKELY(!asInt32 && std::signbit(d)))) { // true for -0.0
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE bool Value::isInt32ConvertibleDouble(const double& d, int32_t& asInt32)
|
||||
{
|
||||
asInt32 = static_cast<int32_t>(d);
|
||||
if (LIKELY(LIKELY(asInt32 != d) || UNLIKELY(!asInt32 && std::signbit(d)))) { // true for -0.0
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline Value::Value(const double& d)
|
||||
{
|
||||
int32_t asInt32;
|
||||
if (UNLIKELY(isInt32ConvertibleDouble(d, asInt32))) {
|
||||
*this = Value(asInt32);
|
||||
return;
|
||||
}
|
||||
*this = Value(static_cast<int32_t>(d));
|
||||
#ifdef ESCARGOT_64
|
||||
if (UNLIKELY((bitwise_cast<int64_t>(d) & DoubleInvalidBeginning) == DoubleInvalidBeginning)) {
|
||||
*this = Value(EncodeAsDouble, std::numeric_limits<double>::quiet_NaN());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
*this = Value(EncodeAsDouble, d);
|
||||
}
|
||||
|
||||
inline Value::Value(char i)
|
||||
|
|
@ -626,25 +645,28 @@ inline Value::Value(unsigned short i)
|
|||
|
||||
inline Value::Value(unsigned i)
|
||||
{
|
||||
if (static_cast<int32_t>(i) < 0) {
|
||||
const int32_t asInt32 = static_cast<int32_t>(i);
|
||||
if (UNLIKELY(asInt32 < 0)) {
|
||||
*this = Value(EncodeAsDouble, static_cast<double>(i));
|
||||
return;
|
||||
}
|
||||
*this = Value(static_cast<int32_t>(i));
|
||||
*this = Value(asInt32);
|
||||
}
|
||||
|
||||
inline Value::Value(long i)
|
||||
{
|
||||
if (static_cast<int32_t>(i) != i) {
|
||||
const int32_t asInt32 = static_cast<int32_t>(i);
|
||||
if (UNLIKELY(asInt32 != i)) {
|
||||
*this = Value(EncodeAsDouble, static_cast<double>(i));
|
||||
return;
|
||||
}
|
||||
*this = Value(static_cast<int32_t>(i));
|
||||
*this = Value(asInt32);
|
||||
}
|
||||
|
||||
inline Value::Value(unsigned long i)
|
||||
{
|
||||
if (static_cast<uint32_t>(i) != i) {
|
||||
const uint32_t asInt32 = static_cast<uint32_t>(i);
|
||||
if (UNLIKELY(asInt32 != i)) {
|
||||
*this = Value(EncodeAsDouble, static_cast<double>(i));
|
||||
return;
|
||||
}
|
||||
|
|
@ -653,20 +675,22 @@ inline Value::Value(unsigned long i)
|
|||
|
||||
inline Value::Value(long long i)
|
||||
{
|
||||
if (static_cast<int32_t>(i) != i) {
|
||||
const int32_t asInt32 = static_cast<int32_t>(i);
|
||||
if (UNLIKELY(asInt32 != i)) {
|
||||
*this = Value(EncodeAsDouble, static_cast<double>(i));
|
||||
return;
|
||||
}
|
||||
*this = Value(static_cast<int32_t>(i));
|
||||
*this = Value(asInt32);
|
||||
}
|
||||
|
||||
inline Value::Value(unsigned long long i)
|
||||
{
|
||||
if (static_cast<uint32_t>(i) != i) {
|
||||
const uint32_t asInt32 = static_cast<uint32_t>(i);
|
||||
if (UNLIKELY(asInt32 != i)) {
|
||||
*this = Value(EncodeAsDouble, static_cast<double>(i));
|
||||
return;
|
||||
}
|
||||
*this = Value(static_cast<uint32_t>(i));
|
||||
*this = Value(asInt32);
|
||||
}
|
||||
|
||||
inline bool Value::isUInt32() const
|
||||
|
|
@ -887,7 +911,7 @@ uint32_t Value::tryToUseAsIndexProperty(ExecutionState& ec) const
|
|||
|
||||
inline double Value::toInteger(ExecutionState& state) const
|
||||
{
|
||||
if (isInt32()) {
|
||||
if (LIKELY(isInt32())) {
|
||||
return asInt32();
|
||||
}
|
||||
|
||||
|
|
@ -903,7 +927,7 @@ inline double Value::toInteger(ExecutionState& state) const
|
|||
|
||||
inline bool Value::isInteger(ExecutionState& state) const
|
||||
{
|
||||
if (isInt32()) {
|
||||
if (LIKELY(isInt32())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -917,7 +941,7 @@ inline bool Value::isInteger(ExecutionState& state) const
|
|||
inline uint64_t Value::toLength(ExecutionState& state) const
|
||||
{
|
||||
double len = toInteger(state);
|
||||
if (len <= 0.0) {
|
||||
if (UNLIKELY(len <= 0.0)) {
|
||||
return 0;
|
||||
}
|
||||
return std::min(len, maximumLength());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue