Commit d60960dc authored by mrowe@apple.com's avatar mrowe@apple.com

Roll out r49004 since it broke the debug build.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@49005 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 71a0340c
2009-10-01 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
Take one branch instead of two to test for JSValue().
1.1% SunSpider speedup.
* jit/JITCall.cpp:
(JSC::JIT::compileOpCall):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_to_jsnumber):
(JSC::JIT::emit_op_create_arguments):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::emit_op_put_by_val): Test for the empty value tag, instead
of testing for the cell tag with a 0 payload.
* runtime/JSValue.cpp:
(JSC::JSValue::description): Added support for dumping the new empty value,
and deleted values, in debug builds.
* runtime/JSValue.h:
(JSC::JSValue::JSValue()): Construct JSValue() with the empty value tag.
(JSC::JSValue::JSValue(JSCell*)): Convert null pointer to the empty value
tag, to avoid having two different c++ versions of null / empty.
(JSC::JSValue::operator bool): Test for the empty value tag, instead
of testing for the cell tag with a 0 payload.
2009-10-01 Yongjun Zhang <yongjun.zhang@nokia.com>
Reviewed by Darin Adler.
......
......@@ -236,14 +236,16 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
int argCount = instruction[3].u.operand;
int registerOffset = instruction[4].u.operand;
Jump wasEval;
Jump wasEval1;
Jump wasEval2;
if (opcodeID == op_call_eval) {
JITStubCall stubCall(this, cti_op_call_eval);
stubCall.addArgument(callee);
stubCall.addArgument(JIT::Imm32(registerOffset));
stubCall.addArgument(JIT::Imm32(argCount));
stubCall.call();
wasEval = branch32(Equal, regT1, Imm32(JSValue::EmptyValueTag));
wasEval1 = branchTest32(NonZero, regT0);
wasEval2 = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
}
emitLoad(callee, regT1, regT2);
......@@ -269,8 +271,10 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
emitNakedCall(m_globalData->jitStubs.ctiVirtualCall());
if (opcodeID == op_call_eval)
wasEval.link(this);
if (opcodeID == op_call_eval) {
wasEval1.link(this);
wasEval2.link(this);
}
emitStore(dst, regT1, regT0);;
......@@ -302,14 +306,16 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
int argCount = instruction[3].u.operand;
int registerOffset = instruction[4].u.operand;
Jump wasEval;
Jump wasEval1;
Jump wasEval2;
if (opcodeID == op_call_eval) {
JITStubCall stubCall(this, cti_op_call_eval);
stubCall.addArgument(callee);
stubCall.addArgument(JIT::Imm32(registerOffset));
stubCall.addArgument(JIT::Imm32(argCount));
stubCall.call();
wasEval = branch32(NotEqual, regT1, Imm32(JSValue::EmptyValueTag));
wasEval1 = branchTest32(NonZero, regT0);
wasEval2 = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
}
emitLoad(callee, regT1, regT0);
......@@ -353,8 +359,10 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
// Call to the callee
m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall();
if (opcodeID == op_call_eval)
wasEval.link(this);
if (opcodeID == op_call_eval) {
wasEval1.link(this);
wasEval2.link(this);
}
// Put the return value in dst. In the interpreter, op_ret does this.
emitStore(dst, regT1, regT0);
......
......@@ -248,8 +248,10 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
addPtr(Imm32(NativeCallFrameSize - sizeof(NativeFunctionCalleeSignature)), stackPointerRegister);
// Check for an exception
// FIXME: Maybe we can optimize this comparison to JSValue().
move(ImmPtr(&globalData->exception), regT2);
Jump sawException = branch32(NotEqual, tagFor(0, regT2), Imm32(JSValue::EmptyValueTag));
Jump sawException1 = branch32(NotEqual, tagFor(0, regT2), Imm32(JSValue::CellTag));
Jump sawException2 = branch32(NonZero, payloadFor(0, regT2), Imm32(0));
// Grab the return address.
emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT3);
......@@ -262,7 +264,8 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
ret();
// Handle an exception
sawException.link(this);
sawException1.link(this);
sawException2.link(this);
// Grab the return address.
emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
move(ImmPtr(&globalData->exceptionLocation), regT2);
......@@ -1234,7 +1237,7 @@ void JIT::emit_op_to_jsnumber(Instruction* currentInstruction)
emitLoad(src, regT1, regT0);
Jump isInt32 = branch32(Equal, regT1, Imm32(JSValue::Int32Tag));
addSlowCase(branch32(AboveOrEqual, regT1, Imm32(JSValue::EmptyValueTag)));
addSlowCase(branch32(AboveOrEqual, regT1, Imm32(JSValue::DeletedValueTag)));
isInt32.link(this);
if (src != dst)
......@@ -1378,7 +1381,8 @@ void JIT::emit_op_enter_with_activation(Instruction* currentInstruction)
void JIT::emit_op_create_arguments(Instruction*)
{
Jump argsCreated = branch32(NotEqual, tagFor(RegisterFile::ArgumentsRegister, callFrameRegister), Imm32(JSValue::EmptyValueTag));
Jump argsNotCell = branch32(NotEqual, tagFor(RegisterFile::ArgumentsRegister, callFrameRegister), Imm32(JSValue::CellTag));
Jump argsNotNull = branchTestPtr(NonZero, payloadFor(RegisterFile::ArgumentsRegister, callFrameRegister));
// If we get here the arguments pointer is a null cell - i.e. arguments need lazy creation.
if (m_codeBlock->m_numParameters == 1)
......@@ -1386,7 +1390,8 @@ void JIT::emit_op_create_arguments(Instruction*)
else
JITStubCall(this, cti_op_create_arguments).call();
argsCreated.link(this);
argsNotCell.link(this);
argsNotNull.link(this);
}
void JIT::emit_op_init_arguments(Instruction*)
......
......@@ -310,8 +310,12 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
// Missed the fast region, but it is still in the vector.
load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag
load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload
branch32(Equal, regT1, Imm32(JSValue::EmptyValueTag)).linkTo(callGetByValJITStub, this);
// FIXME: Maybe we can optimize this comparison to JSValue().
Jump skip = branch32(NotEqual, regT0, Imm32(0));
branch32(Equal, regT1, Imm32(JSValue::CellTag), callGetByValJITStub);
skip.link(this);
emitStore(dst, regT1, regT0);
}
......@@ -329,13 +333,15 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3);
Jump inFastVector = branch32(Below, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff)));
// Check if the access is within the vector.
addSlowCase(branch32(AboveOrEqual, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength))));
// This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location.
// FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff.
addSlowCase(branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), Imm32(JSValue::EmptyValueTag)));
Jump skip = branch32(NotEqual, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), Imm32(JSValue::CellTag));
addSlowCase(branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), Imm32(0)));
skip.link(this);
inFastVector.link(this);
......
......@@ -122,13 +122,9 @@ char* JSValue::description()
snprintf(description, size, "False");
else if (isNull())
snprintf(description, size, "Null");
else if (isUndefined())
snprintf(description, size, "Undefined");
else if (tag() == EmptyValueTag)
snprintf(description, size, "<JSValue()>");
else {
ASSERT(tag() == DeletedValueTag);
snprintf(description, size, "<HashTableDeletedValue>");
ASSERT(isUndefined());
snprintf(description, size, "Undefined");
}
return description;
......
......@@ -213,8 +213,7 @@ namespace JSC {
enum { FalseTag = 0xfffffffc };
enum { NullTag = 0xfffffffb };
enum { UndefinedTag = 0xfffffffa };
enum { EmptyValueTag = 0xfffffff9 };
enum { DeletedValueTag = 0xfffffff8 };
enum { DeletedValueTag = 0xfffffff9 };
enum { LowestTag = DeletedValueTag };
......@@ -428,7 +427,7 @@ namespace JSC {
inline JSValue::JSValue()
{
u.asBits.tag = EmptyValueTag;
u.asBits.tag = CellTag;
u.asBits.payload = 0;
}
......@@ -464,26 +463,19 @@ namespace JSC {
inline JSValue::JSValue(JSCell* ptr)
{
if (ptr)
u.asBits.tag = CellTag;
else
u.asBits.tag = EmptyValueTag;
u.asBits.tag = CellTag;
u.asBits.payload = reinterpret_cast<int32_t>(ptr);
}
inline JSValue::JSValue(const JSCell* ptr)
{
if (ptr)
u.asBits.tag = CellTag;
else
u.asBits.tag = EmptyValueTag;
u.asBits.tag = CellTag;
u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
}
inline JSValue::operator bool() const
{
ASSERT(tag() != DeletedValueTag);
return tag() != EmptyValueTag;
return u.asBits.payload || tag() != CellTag;
}
inline bool JSValue::operator==(const JSValue& other) const
......
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