Commit f62e368c authored by barraclough@apple.com's avatar barraclough@apple.com

Bug 58057 - Store boolean payload in low bit of JSImmediate

Reviewed by Geoff Garen.

And remove some uncalled functions from JSImmediate.h

* jit/JITInlineMethods.h:
(JSC::JIT::emitTagAsBoolImmediate):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_not):
* runtime/JSImmediate.h:
(JSC::JSImmediate::makeInt):
(JSC::JSImmediate::makeBool):
(JSC::JSImmediate::intValue):
(JSC::JSImmediate::boolValue):
(JSC::JSImmediate::asInt32):
(JSC::JSImmediate::toDouble):
(JSC::JSValue::asInt32):
(JSC::JSValue::isUInt32):
(JSC::JSValue::asUInt32):



git-svn-id: svn://svn.chromium.org/blink/trunk@83192 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent dd5827fe
2011-04-06 Gavin Barraclough <barraclough@apple.com>
Reviewed by Geoff Garen.
Bug 58057 - Store boolean payload in low bit of JSImmediate
And remove some uncalled functions from JSImmediate.h
* jit/JITInlineMethods.h:
(JSC::JIT::emitTagAsBoolImmediate):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_not):
* runtime/JSImmediate.h:
(JSC::JSImmediate::makeInt):
(JSC::JSImmediate::makeBool):
(JSC::JSImmediate::intValue):
(JSC::JSImmediate::boolValue):
(JSC::JSImmediate::asInt32):
(JSC::JSImmediate::toDouble):
(JSC::JSValue::asInt32):
(JSC::JSValue::isUInt32):
(JSC::JSValue::asUInt32):
2011-04-07 Liang Qi <liang.qi@nokia.com> 2011-04-07 Liang Qi <liang.qi@nokia.com>
Reviewed by Laszlo Gombos. Reviewed by Laszlo Gombos.
......
...@@ -810,8 +810,7 @@ ALWAYS_INLINE void JIT::emitFastArithIntToImmNoCheck(RegisterID src, RegisterID ...@@ -810,8 +810,7 @@ ALWAYS_INLINE void JIT::emitFastArithIntToImmNoCheck(RegisterID src, RegisterID
ALWAYS_INLINE void JIT::emitTagAsBoolImmediate(RegisterID reg) ALWAYS_INLINE void JIT::emitTagAsBoolImmediate(RegisterID reg)
{ {
lshift32(TrustedImm32(JSImmediate::ExtendedPayloadShift), reg); or32(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeFalse)), reg);
or32(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), reg);
} }
#endif // USE(JSVALUE32_64) #endif // USE(JSVALUE32_64)
......
...@@ -695,9 +695,14 @@ void JIT::emitSlow_op_resolve_global(Instruction* currentInstruction, Vector<Slo ...@@ -695,9 +695,14 @@ void JIT::emitSlow_op_resolve_global(Instruction* currentInstruction, Vector<Slo
void JIT::emit_op_not(Instruction* currentInstruction) void JIT::emit_op_not(Instruction* currentInstruction)
{ {
emitGetVirtualRegister(currentInstruction[2].u.operand, regT0); emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
xorPtr(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0);
addSlowCase(branchTestPtr(NonZero, regT0, TrustedImm32(static_cast<int32_t>(~JSImmediate::ExtendedPayloadBitBoolValue)))); // Invert agains JSValue(false); if the value was tagged as a boolean, when all bits will be
xorPtr(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue)), regT0); // clear other than the low bit (which will be 0 or 1 for false or true inputs respectively).
// Then invert against JSValue(truee), which will add the tag back in, and flip the low bit.
xorPtr(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeFalse)), regT0);
addSlowCase(branchTestPtr(NonZero, regT0, TrustedImm32(static_cast<int32_t>(~1))));
xorPtr(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeTrue)), regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand); emitPutVirtualRegister(currentInstruction[1].u.operand);
} }
...@@ -1374,7 +1379,7 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas ...@@ -1374,7 +1379,7 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas
void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{ {
linkSlowCase(iter); linkSlowCase(iter);
xorPtr(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0); xorPtr(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeFalse)), regT0);
JITStubCall stubCall(this, cti_op_not); JITStubCall stubCall(this, cti_op_not);
stubCall.addArgument(regT0); stubCall.addArgument(regT0);
stubCall.call(currentInstruction[1].u.operand); stubCall.call(currentInstruction[1].u.operand);
......
...@@ -90,7 +90,7 @@ namespace JSC { ...@@ -90,7 +90,7 @@ namespace JSC {
* null and undefined values are represented by specific, invalid pointer values: * null and undefined values are represented by specific, invalid pointer values:
* *
* False: 0x06 * False: 0x06
* True: 0x16 * True: 0x07
* Undefined: 0x0a * Undefined: 0x0a
* Null: 0x02 * Null: 0x02
* *
...@@ -137,25 +137,19 @@ namespace JSC { ...@@ -137,25 +137,19 @@ namespace JSC {
// This value is 2^48, used to encode doubles such that the encoded value will begin // This value is 2^48, used to encode doubles such that the encoded value will begin
// with a 16-bit pattern within the range 0x0001..0xFFFE. // with a 16-bit pattern within the range 0x0001..0xFFFE.
static const intptr_t DoubleEncodeOffset = 0x1000000000000ll; static const intptr_t DoubleEncodeOffset = 0x1000000000000ll;
static const intptr_t TagBitTypeOther = 0x2; // second bit set indicates immediate other than an integer // The second bit set indicates immediate other than an number (bool, null, undefined).
static const intptr_t TagMask = TagTypeNumber | TagBitTypeOther; static const intptr_t TagBitTypeOther = 0x2;
// TagMask is used to check for any immediate values (number or other).
static const intptr_t TagMask = TagTypeNumber | TagBitTypeOther;
static const intptr_t ExtendedTagMask = 0xC; // extended tag holds a further two bits
static const intptr_t ExtendedTagBitBool = 0x4; static const intptr_t ExtendedTagBitBool = 0x4;
static const intptr_t ExtendedTagBitUndefined = 0x8; static const intptr_t ExtendedTagBitUndefined = 0x8;
static const intptr_t FullTagTypeMask = TagMask | ExtendedTagMask; static const intptr_t FullTagTypeFalse = TagBitTypeOther | ExtendedTagBitBool | false;
static const intptr_t FullTagTypeBool = TagBitTypeOther | ExtendedTagBitBool; static const intptr_t FullTagTypeTrue = TagBitTypeOther | ExtendedTagBitBool | true;
static const intptr_t FullTagTypeUndefined = TagBitTypeOther | ExtendedTagBitUndefined; static const intptr_t FullTagTypeUndefined = TagBitTypeOther | ExtendedTagBitUndefined;
static const intptr_t FullTagTypeNull = TagBitTypeOther; static const intptr_t FullTagTypeNull = TagBitTypeOther;
static const int32_t IntegerPayloadShift = 0;
static const int32_t ExtendedPayloadShift = 4;
static const intptr_t ExtendedPayloadBitBoolValue = 1 << ExtendedPayloadShift;
static const int32_t signBit = 0x80000000;
static ALWAYS_INLINE bool isImmediate(JSValue v) static ALWAYS_INLINE bool isImmediate(JSValue v)
{ {
return rawValue(v) & TagMask; return rawValue(v) & TagMask;
...@@ -176,15 +170,9 @@ namespace JSC { ...@@ -176,15 +170,9 @@ namespace JSC {
return isNumber(v) && !isIntegerNumber(v); return isNumber(v) && !isIntegerNumber(v);
} }
static ALWAYS_INLINE bool isPositiveIntegerNumber(JSValue v)
{
// A single mask to check for the sign bit and the number tag all at once.
return (rawValue(v) & (signBit | TagTypeNumber)) == TagTypeNumber;
}
static ALWAYS_INLINE bool isBoolean(JSValue v) static ALWAYS_INLINE bool isBoolean(JSValue v)
{ {
return (rawValue(v) & FullTagTypeMask) == FullTagTypeBool; return (rawValue(v) & ~1) == FullTagTypeFalse;
} }
static ALWAYS_INLINE bool isUndefinedOrNull(JSValue v) static ALWAYS_INLINE bool isUndefinedOrNull(JSValue v)
...@@ -224,12 +212,9 @@ namespace JSC { ...@@ -224,12 +212,9 @@ namespace JSC {
static double toDouble(JSValue); static double toDouble(JSValue);
static bool toBoolean(JSValue); static bool toBoolean(JSValue);
static bool getUInt32(JSValue, uint32_t&); static bool asInt32(JSValue, int32_t&);
static bool getTruncatedInt32(JSValue, int32_t&);
static bool getTruncatedUInt32(JSValue, uint32_t&);
static int32_t getTruncatedInt32(JSValue); static int32_t asInt32(JSValue);
static uint32_t getTruncatedUInt32(JSValue);
static JSValue trueImmediate(); static JSValue trueImmediate();
static JSValue falseImmediate(); static JSValue falseImmediate();
...@@ -251,9 +236,9 @@ namespace JSC { ...@@ -251,9 +236,9 @@ namespace JSC {
// With USE(JSVALUE64) we want the argument to be zero extended, so the // With USE(JSVALUE64) we want the argument to be zero extended, so the
// integer doesn't interfere with the tag bits in the upper word. In the default encoding, // integer doesn't interfere with the tag bits in the upper word. In the default encoding,
// if intptr_t id larger then int32_t we sign extend the value through the upper word. // if intptr_t id larger then int32_t we sign extend the value through the upper word.
static ALWAYS_INLINE JSValue makeInt(uint32_t value) static ALWAYS_INLINE JSValue makeInt(int32_t value)
{ {
return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagTypeNumber); return makeValue(static_cast<intptr_t>(static_cast<uint32_t>(value)) | TagTypeNumber);
} }
static ALWAYS_INLINE JSValue makeDouble(double value) static ALWAYS_INLINE JSValue makeDouble(double value)
...@@ -263,7 +248,7 @@ namespace JSC { ...@@ -263,7 +248,7 @@ namespace JSC {
static ALWAYS_INLINE JSValue makeBool(bool b) static ALWAYS_INLINE JSValue makeBool(bool b)
{ {
return makeValue((static_cast<intptr_t>(b) << ExtendedPayloadShift) | FullTagTypeBool); return makeValue(static_cast<intptr_t>(b) | FullTagTypeFalse);
} }
static ALWAYS_INLINE JSValue makeUndefined() static ALWAYS_INLINE JSValue makeUndefined()
...@@ -286,17 +271,12 @@ namespace JSC { ...@@ -286,17 +271,12 @@ namespace JSC {
static ALWAYS_INLINE int32_t intValue(JSValue v) static ALWAYS_INLINE int32_t intValue(JSValue v)
{ {
return static_cast<int32_t>(rawValue(v) >> IntegerPayloadShift); return static_cast<int32_t>(rawValue(v));
}
static ALWAYS_INLINE uint32_t uintValue(JSValue v)
{
return static_cast<uint32_t>(rawValue(v) >> IntegerPayloadShift);
} }
static ALWAYS_INLINE bool boolValue(JSValue v) static ALWAYS_INLINE bool boolValue(JSValue v)
{ {
return rawValue(v) & ExtendedPayloadBitBoolValue; return rawValue(v) & 1;
} }
static ALWAYS_INLINE intptr_t rawValue(JSValue v) static ALWAYS_INLINE intptr_t rawValue(JSValue v)
...@@ -324,13 +304,6 @@ namespace JSC { ...@@ -324,13 +304,6 @@ namespace JSC {
: doubleToBoolean(doubleValue(v)) : v == trueImmediate(); : doubleToBoolean(doubleValue(v)) : v == trueImmediate();
} }
ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValue v)
{
// FIXME: should probably be asserting isPositiveIntegerNumber here.
ASSERT(isIntegerNumber(v));
return intValue(v);
}
template<typename T> template<typename T>
inline JSValue JSImmediate::fromNumberOutsideIntegerRange(T value) inline JSValue JSImmediate::fromNumberOutsideIntegerRange(T value)
{ {
...@@ -413,7 +386,7 @@ namespace JSC { ...@@ -413,7 +386,7 @@ namespace JSC {
return from(intVal); return from(intVal);
} }
ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValue v) ALWAYS_INLINE int32_t JSImmediate::asInt32(JSValue v)
{ {
ASSERT(isIntegerNumber(v)); ASSERT(isIntegerNumber(v));
return intValue(v); return intValue(v);
...@@ -435,26 +408,15 @@ namespace JSC { ...@@ -435,26 +408,15 @@ namespace JSC {
return nonInlineNaN(); return nonInlineNaN();
ASSERT(JSImmediate::isBoolean(v) || (v == JSImmediate::nullImmediate())); ASSERT(JSImmediate::isBoolean(v) || (v == JSImmediate::nullImmediate()));
return rawValue(v) >> ExtendedPayloadShift; return boolValue(v);
} }
ALWAYS_INLINE bool JSImmediate::getUInt32(JSValue v, uint32_t& i) ALWAYS_INLINE bool JSImmediate::asInt32(JSValue v, int32_t& i)
{
i = uintValue(v);
return isPositiveIntegerNumber(v);
}
ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(JSValue v, int32_t& i)
{ {
i = intValue(v); i = intValue(v);
return isIntegerNumber(v); return isIntegerNumber(v);
} }
ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(JSValue v, uint32_t& i)
{
return getUInt32(v, i);
}
inline JSValue::JSValue(JSNullTag) inline JSValue::JSValue(JSNullTag)
{ {
*this = JSImmediate::nullImmediate(); *this = JSImmediate::nullImmediate();
...@@ -523,18 +485,18 @@ namespace JSC { ...@@ -523,18 +485,18 @@ namespace JSC {
inline int32_t JSValue::asInt32() const inline int32_t JSValue::asInt32() const
{ {
ASSERT(isInt32()); ASSERT(isInt32());
return JSImmediate::getTruncatedInt32(asValue()); return JSImmediate::asInt32(asValue());
} }
inline bool JSValue::isUInt32() const inline bool JSValue::isUInt32() const
{ {
return JSImmediate::isPositiveIntegerNumber(asValue()); return isInt32() && asInt32() > -1;
} }
inline uint32_t JSValue::asUInt32() const inline uint32_t JSValue::asUInt32() const
{ {
ASSERT(isUInt32()); ASSERT(isUInt32());
return JSImmediate::getTruncatedUInt32(asValue()); return asInt32();
} }
} // namespace JSC } // namespace JSC
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment