Commit 9d4f0eca authored by oliver@apple.com's avatar oliver@apple.com

2011-03-11 Oliver Hunt <oliver@apple.com>

        Reviewed by Gavin Barraclough.

        Ensure all values are correctly tagged in the registerfile
        https://bugs.webkit.org/show_bug.cgi?id=56214

        This patch makes sure that all JSCell pointers written to
        the registerfile are correctly tagged as JSCells, and replaces
        raw int usage with the immediate representation.

        For performance, register pressure, and general saneness reasons
        I've added abstractions for reading and writing the tag
        and payload of integer registers directly for the JSVALUE64
        encoding.

        * interpreter/Register.h:
        (JSC::Register::withInt):
        (JSC::Register::withCallee):
        (JSC::Register::operator=):
        (JSC::Register::i):
        (JSC::Register::activation):
        (JSC::Register::function):
        (JSC::Register::propertyNameIterator):
        (JSC::Register::scopeChain):
        * jit/JIT.h:
        * jit/JITCall.cpp:
        (JSC::JIT::compileOpCallInitializeCallFrame):
        (JSC::JIT::compileOpCallVarargs):
        (JSC::JIT::compileOpCall):
        * jit/JITCall32_64.cpp:
        (JSC::JIT::compileOpCallInitializeCallFrame):
        (JSC::JIT::compileOpCallVarargs):
        (JSC::JIT::compileOpCall):
        (JSC::JIT::compileOpCallSlowCase):
        * jit/JITInlineMethods.h:
        (JSC::JIT::emitPutToCallFrameHeader):
        (JSC::JIT::emitPutCellToCallFrameHeader):
        (JSC::JIT::emitPutIntToCallFrameHeader):
        * jit/JITOpcodes.cpp:
        (JSC::JIT::privateCompileCTINativeCall):
        (JSC::JIT::emit_op_get_pnames):
        (JSC::JIT::emit_op_next_pname):
        (JSC::JIT::emit_op_load_varargs):
        (JSC::JIT::emitSlow_op_load_varargs):
        * jit/JITOpcodes32_64.cpp:
        (JSC::JIT::privateCompileCTINativeCall):
        (JSC::JIT::emit_op_get_pnames):
        (JSC::JIT::emit_op_next_pname):
        * jit/JSInterfaceJIT.h:
        (JSC::JSInterfaceJIT::intPayloadFor):
        (JSC::JSInterfaceJIT::intTagFor):
        * jit/SpecializedThunkJIT.h:
        (JSC::SpecializedThunkJIT::returnJSValue):
        (JSC::SpecializedThunkJIT::returnDouble):
        (JSC::SpecializedThunkJIT::returnInt32):
        (JSC::SpecializedThunkJIT::returnJSCell):
2011-03-11  Oliver Hunt  <oliver@apple.com>

        Reviewed by Gavin Barraclough.

        Ensure all values are correctly tagged in the registerfile
        https://bugs.webkit.org/show_bug.cgi?id=56214

        Make sure everything builds still.

        * bridge/c/c_class.cpp:
        * bridge/c/c_runtime.cpp:
        * bridge/jni/JavaMethod.cpp:
        * plugins/PluginViewNone.cpp:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@81040 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 1a0f8448
2011-03-11 Oliver Hunt <oliver@apple.com>
Reviewed by Gavin Barraclough.
Ensure all values are correctly tagged in the registerfile
https://bugs.webkit.org/show_bug.cgi?id=56214
This patch makes sure that all JSCell pointers written to
the registerfile are correctly tagged as JSCells, and replaces
raw int usage with the immediate representation.
For performance, register pressure, and general saneness reasons
I've added abstractions for reading and writing the tag
and payload of integer registers directly for the JSVALUE64
encoding.
* interpreter/Register.h:
(JSC::Register::withInt):
(JSC::Register::withCallee):
(JSC::Register::operator=):
(JSC::Register::i):
(JSC::Register::activation):
(JSC::Register::function):
(JSC::Register::propertyNameIterator):
(JSC::Register::scopeChain):
* jit/JIT.h:
* jit/JITCall.cpp:
(JSC::JIT::compileOpCallInitializeCallFrame):
(JSC::JIT::compileOpCallVarargs):
(JSC::JIT::compileOpCall):
* jit/JITCall32_64.cpp:
(JSC::JIT::compileOpCallInitializeCallFrame):
(JSC::JIT::compileOpCallVarargs):
(JSC::JIT::compileOpCall):
(JSC::JIT::compileOpCallSlowCase):
* jit/JITInlineMethods.h:
(JSC::JIT::emitPutToCallFrameHeader):
(JSC::JIT::emitPutCellToCallFrameHeader):
(JSC::JIT::emitPutIntToCallFrameHeader):
* jit/JITOpcodes.cpp:
(JSC::JIT::privateCompileCTINativeCall):
(JSC::JIT::emit_op_get_pnames):
(JSC::JIT::emit_op_next_pname):
(JSC::JIT::emit_op_load_varargs):
(JSC::JIT::emitSlow_op_load_varargs):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::privateCompileCTINativeCall):
(JSC::JIT::emit_op_get_pnames):
(JSC::JIT::emit_op_next_pname):
* jit/JSInterfaceJIT.h:
(JSC::JSInterfaceJIT::intPayloadFor):
(JSC::JSInterfaceJIT::intTagFor):
* jit/SpecializedThunkJIT.h:
(JSC::SpecializedThunkJIT::returnJSValue):
(JSC::SpecializedThunkJIT::returnDouble):
(JSC::SpecializedThunkJIT::returnInt32):
(JSC::SpecializedThunkJIT::returnJSCell):
2011-03-13 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
......
......@@ -26,6 +26,7 @@
#include "config.h"
#include "StructureStubInfo.h"
#include "JSObject.h"
#include "ScopeChain.h"
namespace JSC {
......
......@@ -56,10 +56,8 @@ namespace JSC {
JSValue jsValue() const;
EncodedJSValue encodedJSValue() const;
Register& operator=(JSActivation*);
Register& operator=(CallFrame*);
Register& operator=(CodeBlock*);
Register& operator=(JSPropertyNameIterator*);
Register& operator=(ScopeChainNode*);
Register& operator=(Instruction*);
......@@ -74,29 +72,17 @@ namespace JSC {
static Register withInt(int32_t i)
{
Register r;
r.u.i = i;
Register r = jsNumber(i);
return r;
}
static Register withCallee(JSObject* callee)
{
Register r;
r.u.function = callee;
return r;
}
static inline Register withCallee(JSObject* callee);
private:
union {
int32_t i;
EncodedJSValue value;
JSActivation* activation;
CallFrame* callFrame;
CodeBlock* codeBlock;
JSObject* function;
JSPropertyNameIterator* propertyNameIterator;
ScopeChainNode* scopeChain;
Instruction* vPC;
} u;
};
......@@ -137,12 +123,6 @@ namespace JSC {
// Interpreter functions
ALWAYS_INLINE Register& Register::operator=(JSActivation* activation)
{
u.activation = activation;
return *this;
}
ALWAYS_INLINE Register& Register::operator=(CallFrame* callFrame)
{
u.callFrame = callFrame;
......@@ -161,28 +141,11 @@ namespace JSC {
return *this;
}
ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain)
{
u.scopeChain = scopeChain;
return *this;
}
ALWAYS_INLINE Register& Register::operator=(JSPropertyNameIterator* propertyNameIterator)
{
u.propertyNameIterator = propertyNameIterator;
return *this;
}
ALWAYS_INLINE int32_t Register::i() const
{
return u.i;
return jsValue().asInt32();
}
ALWAYS_INLINE JSActivation* Register::activation() const
{
return u.activation;
}
ALWAYS_INLINE CallFrame* Register::callFrame() const
{
return u.callFrame;
......@@ -192,22 +155,7 @@ namespace JSC {
{
return u.codeBlock;
}
ALWAYS_INLINE JSObject* Register::function() const
{
return u.function;
}
ALWAYS_INLINE JSPropertyNameIterator* Register::propertyNameIterator() const
{
return u.propertyNameIterator;
}
ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const
{
return u.scopeChain;
}
ALWAYS_INLINE Instruction* Register::vPC() const
{
return u.vPC;
......
......@@ -853,6 +853,8 @@ namespace JSC {
void emitInitRegister(unsigned dst);
void emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry);
void emitPutCellToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry);
void emitPutIntToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry);
void emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry);
void emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from = callFrameRegister);
void emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from = callFrameRegister);
......
......@@ -48,10 +48,11 @@ namespace JSC {
void JIT::compileOpCallInitializeCallFrame()
{
store32(regT1, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register))));
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), regT3); // newScopeChain
storePtr(regT0, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register))));
storePtr(regT3, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register))));
// regT0 holds callee, regT1 holds argCount
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), regT3); // scopeChain
emitPutIntToCallFrameHeader(regT1, RegisterFile::ArgumentCount);
emitPutCellToCallFrameHeader(regT0, RegisterFile::Callee);
emitPutCellToCallFrameHeader(regT3, RegisterFile::ScopeChain);
}
void JIT::emit_op_call_put_result(Instruction* instruction)
......@@ -67,6 +68,7 @@ void JIT::compileOpCallVarargs(Instruction* instruction)
int registerOffset = instruction[3].u.operand;
emitGetVirtualRegister(argCountRegister, regT1);
emitFastArithImmToInt(regT1);
emitGetVirtualRegister(callee, regT0);
addPtr(Imm32(registerOffset), regT1, regT2);
......@@ -199,8 +201,9 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
// Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), regT1); // newScopeChain
store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register))));
store32(Imm32(Int32Tag), intTagFor(registerOffset + RegisterFile::ArgumentCount));
store32(Imm32(argCount), intPayloadFor(registerOffset + RegisterFile::ArgumentCount));
storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register))));
storePtr(regT0, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register))));
storePtr(regT1, Address(callFrameRegister, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register))));
......
......@@ -49,10 +49,10 @@ namespace JSC {
void JIT::compileOpCallInitializeCallFrame()
{
// regT0 holds callee, regT1 holds argCount
store32(regT1, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register))));
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), regT3); // scopeChain
storePtr(regT0, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register)))); // callee
storePtr(regT3, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register)))); // scopeChain
emitPutIntToCallFrameHeader(regT1, RegisterFile::ArgumentCount);
emitPutCellToCallFrameHeader(regT0, RegisterFile::Callee);
emitPutCellToCallFrameHeader(regT3, RegisterFile::ScopeChain);
}
void JIT::emit_op_call_put_result(Instruction* instruction)
......@@ -77,7 +77,8 @@ void JIT::compileOpCallVarargs(Instruction* instruction)
// Speculatively roll the callframe, assuming argCount will match the arity.
mul32(Imm32(sizeof(Register)), regT3, regT3);
addPtr(callFrameRegister, regT3);
storePtr(callFrameRegister, Address(regT3, RegisterFile::CallerFrame * static_cast<int>(sizeof(Register))));
store32(Imm32(JSValue::CellTag), tagFor(RegisterFile::CallerFrame, regT3));
storePtr(callFrameRegister, payloadFor(RegisterFile::CallerFrame, regT3));
move(regT3, callFrameRegister);
move(regT2, regT1); // argCount
......@@ -208,7 +209,8 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr)));
// Speculatively roll the callframe, assuming argCount will match the arity.
storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
store32(Imm32(JSValue::CellTag), tagFor(RegisterFile::CallerFrame + registerOffset, callFrameRegister));
storePtr(callFrameRegister, payloadFor(RegisterFile::CallerFrame + registerOffset, callFrameRegister));
addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
move(Imm32(argCount), regT1);
......@@ -280,10 +282,12 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
// Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), regT2);
store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register))));
storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register))));
store32(Imm32(JSValue::Int32Tag), tagFor(registerOffset + RegisterFile::ArgumentCount));
store32(Imm32(argCount), payloadFor(registerOffset + RegisterFile::ArgumentCount));
storePtr(callFrameRegister, payloadFor(RegisterFile::CallerFrame + registerOffset, callFrameRegister));
emitStore(registerOffset + RegisterFile::Callee, regT1, regT0);
storePtr(regT2, Address(callFrameRegister, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register))));
store32(Imm32(JSValue::CellTag), tagFor(registerOffset + RegisterFile::ScopeChain));
store32(regT2, payloadFor(registerOffset + RegisterFile::ScopeChain));
addPtr(Imm32(registerOffset * sizeof(Register)), callFrameRegister);
// Call to the callee
......@@ -309,7 +313,8 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>:
Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr));
// Speculatively roll the callframe, assuming argCount will match the arity.
storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
store32(Imm32(JSValue::CellTag), tagFor(RegisterFile::CallerFrame + registerOffset, callFrameRegister));
storePtr(callFrameRegister, payloadFor(RegisterFile::CallerFrame + registerOffset, callFrameRegister));
addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
move(Imm32(argCount), regT1);
......
......@@ -52,7 +52,21 @@ ALWAYS_INLINE JSValue JIT::getConstantOperand(unsigned src)
ALWAYS_INLINE void JIT::emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry)
{
storePtr(from, Address(callFrameRegister, entry * sizeof(Register)));
storePtr(from, payloadFor(entry, callFrameRegister));
}
ALWAYS_INLINE void JIT::emitPutCellToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry)
{
#if USE(JSVALUE32_64)
store32(Imm32(JSValue::CellTag), tagFor(entry, callFrameRegister));
#endif
storePtr(from, payloadFor(entry, callFrameRegister));
}
ALWAYS_INLINE void JIT::emitPutIntToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry)
{
store32(Imm32(Int32Tag), intTagFor(entry, callFrameRegister));
store32(from, intPayloadFor(entry, callFrameRegister));
}
ALWAYS_INLINE void JIT::emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry)
......
......@@ -199,7 +199,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
peek(regT1);
emitPutToCallFrameHeader(regT1, RegisterFile::ReturnPC);
......@@ -222,7 +222,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2);
emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
preserveReturnAddressAfterCall(regT3); // Callee preserved
emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
......@@ -243,7 +243,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
preserveReturnAddressAfterCall(regT3); // Callee preserved
emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
......@@ -902,8 +902,9 @@ void JIT::emit_op_get_pnames(Instruction* currentInstruction)
getPnamesStubCall.addArgument(regT0);
getPnamesStubCall.call(dst);
load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3);
store32(Imm32(0), addressFor(i));
store32(regT3, addressFor(size));
storePtr(tagTypeNumberRegister, payloadFor(i));
store32(Imm32(Int32Tag), intTagFor(size));
store32(regT3, intPayloadFor(size));
Jump end = jump();
isNotObject.link(this);
......@@ -931,8 +932,8 @@ void JIT::emit_op_next_pname(Instruction* currentInstruction)
JumpList callHasProperty;
Label begin(this);
load32(addressFor(i), regT0);
Jump end = branch32(Equal, regT0, addressFor(size));
load32(intPayloadFor(i), regT0);
Jump end = branch32(Equal, regT0, intPayloadFor(size));
// Grab key @ i
loadPtr(addressFor(it), regT1);
......@@ -944,7 +945,7 @@ void JIT::emit_op_next_pname(Instruction* currentInstruction)
// Increment i
add32(Imm32(1), regT0);
store32(regT0, addressFor(i));
store32(regT0, intPayloadFor(i));
// Verify that i is valid:
emitGetVirtualRegister(base, regT0);
......@@ -1689,7 +1690,8 @@ void JIT::emit_op_load_varargs(Instruction* currentInstruction)
#endif
// Load arg count into regT0
emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
storePtr(regT0, addressFor(argCountDst));
store32(Imm32(Int32Tag), intTagFor(argCountDst));
store32(regT0, intPayloadFor(argCountDst));
Jump endBranch = branch32(Equal, regT0, Imm32(1));
mul32(Imm32(sizeof(Register)), regT0, regT3);
......@@ -1727,8 +1729,9 @@ void JIT::emitSlow_op_load_varargs(Instruction* currentInstruction, Vector<SlowC
JITStubCall stubCall(this, cti_op_load_varargs);
stubCall.addArgument(Imm32(argsOffset));
stubCall.call();
// Stores a naked int32 in the register file.
store32(returnValueRegister, Address(callFrameRegister, argCountDst * sizeof(Register)));
store32(Imm32(Int32Tag), intTagFor(argCountDst));
store32(returnValueRegister, intPayloadFor(argCountDst));
}
void JIT::emit_op_new_func(Instruction* currentInstruction)
......
......@@ -205,7 +205,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
peek(regT1);
emitPutToCallFrameHeader(regT1, RegisterFile::ReturnPC);
......@@ -229,7 +229,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2);
emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
preserveReturnAddressAfterCall(regT3); // Callee preserved
emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
......@@ -251,7 +251,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
preserveReturnAddressAfterCall(regT3); // Callee preserved
emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
......@@ -321,7 +321,7 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
peek(regT1);
emitPutToCallFrameHeader(regT1, RegisterFile::ReturnPC);
......@@ -344,7 +344,7 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2);
emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
preserveReturnAddressAfterCall(regT3); // Callee preserved
emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
......@@ -367,7 +367,7 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain);
preserveReturnAddressAfterCall(regT3); // Callee preserved
emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
......@@ -1276,8 +1276,10 @@ void JIT::emit_op_get_pnames(Instruction* currentInstruction)
getPnamesStubCall.addArgument(regT0);
getPnamesStubCall.call(dst);
load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3);
store32(Imm32(0), addressFor(i));
store32(regT3, addressFor(size));
store32(Imm32(Int32Tag), intTagFor(i));
store32(Imm32(0), intPayloadFor(i));
store32(Imm32(Int32Tag), intTagFor(size));
store32(regT3, payloadFor(size));
Jump end = jump();
isNotObject.link(this);
......@@ -1303,11 +1305,11 @@ void JIT::emit_op_next_pname(Instruction* currentInstruction)
JumpList callHasProperty;
Label begin(this);
load32(addressFor(i), regT0);
Jump end = branch32(Equal, regT0, addressFor(size));
load32(intPayloadFor(i), regT0);
Jump end = branch32(Equal, regT0, intPayloadFor(size));
// Grab key @ i
loadPtr(addressFor(it), regT1);
loadPtr(payloadFor(it), regT1);
loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2);
load32(BaseIndex(regT2, regT0, TimesEight), regT2);
store32(Imm32(JSValue::CellTag), tagFor(dst));
......@@ -1315,10 +1317,10 @@ void JIT::emit_op_next_pname(Instruction* currentInstruction)
// Increment i
add32(Imm32(1), regT0);
store32(regT0, addressFor(i));
store32(regT0, intPayloadFor(i));
// Verify that i is valid:
loadPtr(addressFor(base), regT0);
loadPtr(payloadFor(base), regT0);
// Test base's structure
loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
......
......@@ -29,6 +29,7 @@
#include "JITCode.h"
#include "JITStubs.h"
#include "JSImmediate.h"
#include "JSValue.h"
#include "MacroAssembler.h"
#include "RegisterFile.h"
#include <wtf/AlwaysInline.h>
......@@ -157,6 +158,13 @@ namespace JSC {
#error "JIT not supported on this platform."
#endif
#if USE(JSVALUE32_64)
// Can't just propogate JSValue::Int32Tag as visual studio doesn't like it
static const unsigned Int32Tag = 0xfffffffd;
COMPILE_ASSERT(Int32Tag == JSValue::Int32Tag, Int32Tag_out_of_sync);
#else
static const unsigned Int32Tag = JSImmediate::TagTypeNumber >> 32;
#endif
inline Jump emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID payload);
inline Jump emitLoadInt32(unsigned virtualRegisterIndex, RegisterID dst);
inline Jump emitLoadDouble(unsigned virtualRegisterIndex, FPRegisterID dst, RegisterID scratch);
......@@ -173,6 +181,8 @@ namespace JSC {
#endif
inline Address payloadFor(unsigned index, RegisterID base = callFrameRegister);
inline Address intPayloadFor(unsigned index, RegisterID base = callFrameRegister);
inline Address intTagFor(unsigned index, RegisterID base = callFrameRegister);
inline Address addressFor(unsigned index, RegisterID base = callFrameRegister);
};
......@@ -214,6 +224,16 @@ namespace JSC {
return Address(base, (virtualRegisterIndex * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.payload));
}
inline JSInterfaceJIT::Address JSInterfaceJIT::intPayloadFor(unsigned virtualRegisterIndex, RegisterID base)
{
return payloadFor(virtualRegisterIndex, base);
}
inline JSInterfaceJIT::Address JSInterfaceJIT::intTagFor(unsigned virtualRegisterIndex, RegisterID base)
{
return tagFor(virtualRegisterIndex, base);
}
inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadDouble(unsigned virtualRegisterIndex, FPRegisterID dst, RegisterID scratch)
{
ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
......@@ -279,6 +299,17 @@ namespace JSC {
ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
return addressFor(virtualRegisterIndex, base);
}
inline JSInterfaceJIT::Address JSInterfaceJIT::intPayloadFor(unsigned virtualRegisterIndex, RegisterID base)
{
ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
return Address(base, (virtualRegisterIndex * sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
}
inline JSInterfaceJIT::Address JSInterfaceJIT::intTagFor(unsigned virtualRegisterIndex, RegisterID base)
{
ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
return Address(base, (virtualRegisterIndex * sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
}
#endif
inline JSInterfaceJIT::Address JSInterfaceJIT::addressFor(unsigned virtualRegisterIndex, RegisterID base)
......
......@@ -87,7 +87,7 @@ namespace JSC {
{
if (src != regT0)
move(src, regT0);
loadPtr(Address(callFrameRegister, RegisterFile::CallerFrame * (int)sizeof(Register)), callFrameRegister);
loadPtr(payloadFor(RegisterFile::CallerFrame, callFrameRegister), callFrameRegister);
ret();
}
......@@ -101,7 +101,7 @@ namespace JSC {
loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(JSValue, u.asBits.tag) - sizeof(double)), regT1);
loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(JSValue, u.asBits.payload) - sizeof(double)), regT0);
#endif
loadPtr(Address(callFrameRegister, RegisterFile::CallerFrame * (int)sizeof(Register)), callFrameRegister);
loadPtr(payloadFor(RegisterFile::CallerFrame, callFrameRegister), callFrameRegister);
ret();
}
......@@ -110,7 +110,7 @@ namespace JSC {
if (src != regT0)
move(src, regT0);
tagReturnAsInt32();
loadPtr(Address(callFrameRegister, RegisterFile::CallerFrame * (int)sizeof(Register)), callFrameRegister);
loadPtr(payloadFor(RegisterFile::CallerFrame, callFrameRegister), callFrameRegister);
ret();
}
......@@ -119,7 +119,7 @@ namespace JSC {
if (src != regT0)
move(src, regT0);
tagReturnAsJSCell();
loadPtr(Address(callFrameRegister, RegisterFile::CallerFrame * (int)sizeof(Register)), callFrameRegister);
loadPtr(payloadFor(RegisterFile::CallerFrame, callFrameRegister), callFrameRegister);
ret();
}
......
......@@ -23,6 +23,7 @@
#include "JSValue.h"
#include "JSCell.h"
#include "JSObject.h"
#include "ScopeChain.h"
using std::min;
......
......@@ -44,6 +44,7 @@
#include "DateConversion.h"
#include "CallFrame.h"
#include "JSObject.h"
#include "ScopeChain.h"
#include "UString.h"
#include <wtf/DateMath.h>
......
......@@ -33,6 +33,7 @@
#include "Heap.h"
#include "JSGlobalData.h"
#include "JSLock.h"
#include "JSObject.h"
#include "ScopeChain.h"
#include <wtf/RetainPtr.h>
#include <wtf/WTFThreadData.h>
......
......@@ -22,6 +22,7 @@
#include "Identifier.h"
#include "CallFrame.h"
#include "JSObject.h"
#include "NumericStrings.h"
#include "ScopeChain.h"
#include <new> // for placement new
......
......@@ -91,6 +91,11 @@ namespace JSC {
ASSERT(asObject(value)->inherits(&JSActivation::s_info));
return static_cast<JSActivation*>(asObject(value));
}
ALWAYS_INLINE JSActivation* Register::activation() const
{
return asActivation(jsValue());
}
} // namespace JSC
......
......@@ -23,6 +23,7 @@
#include "Heap.h"
#include "CallFrame.h"
#include "JSObject.h"
#include "ScopeChain.h"
#if USE(PTHREADS)
......
......@@ -22,6 +22,7 @@
#include "config.h"
#include "JSNumberCell.h"
#include "JSObject.h"
#include "ScopeChain.h"
// Keep our exported symbols lists happy.
......
......@@ -840,6 +840,20 @@ inline JSValue JSValue::toStrictThisObject(ExecState* exec) const
return asObject(asCell())->toStrictThisObject(exec);
}
ALWAYS_INLINE JSObject* Register::function() const
{
if (!jsValue())