summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/jit
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-06-02 12:07:03 +0100
committerBen Murdoch <benm@google.com>2011-06-10 10:47:21 +0100
commit2daae5fd11344eaa88a0d92b0f6d65f8d2255c00 (patch)
treee4964fbd1cb70599f7718ff03e50ea1dab33890b /Source/JavaScriptCore/jit
parent87bdf0060a247bfbe668342b87e0874182e0ffa9 (diff)
downloadexternal_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.zip
external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.gz
external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.bz2
Merge WebKit at r84325: Initial merge by git.
Change-Id: Ic1a909300ecc0a13ddc6b4e784371d2ac6e3d59b
Diffstat (limited to 'Source/JavaScriptCore/jit')
-rw-r--r--Source/JavaScriptCore/jit/JIT.cpp6
-rw-r--r--Source/JavaScriptCore/jit/JIT.h52
-rw-r--r--Source/JavaScriptCore/jit/JITArithmetic.cpp2
-rw-r--r--Source/JavaScriptCore/jit/JITInlineMethods.h60
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes.cpp31
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes32_64.cpp154
-rw-r--r--Source/JavaScriptCore/jit/JITPropertyAccess.cpp35
-rw-r--r--Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp41
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.cpp134
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.h25
-rw-r--r--Source/JavaScriptCore/jit/JSInterfaceJIT.h35
11 files changed, 405 insertions, 170 deletions
diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp
index 063ae8c..b983427 100644
--- a/Source/JavaScriptCore/jit/JIT.cpp
+++ b/Source/JavaScriptCore/jit/JIT.cpp
@@ -44,6 +44,7 @@ JSC::MacroAssemblerX86Common::SSE2CheckState JSC::MacroAssemblerX86Common::s_sse
#include "RepatchBuffer.h"
#include "ResultType.h"
#include "SamplingTool.h"
+#include "dfg/DFGNode.h" // for DFG_SUCCESS_STATS
using namespace std;
@@ -471,6 +472,11 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
Jump registerFileCheck;
if (m_codeBlock->codeType() == FunctionCode) {
+#if DFG_SUCCESS_STATS
+ static SamplingCounter counter("orignalJIT");
+ emitCount(counter);
+#endif
+
// In the case of a fast linked call, we do not set this up in the caller.
emitPutImmediateToCallFrameHeader(m_codeBlock, RegisterFile::CodeBlock);
diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h
index 61bd2ab..6b8c6dd 100644
--- a/Source/JavaScriptCore/jit/JIT.h
+++ b/Source/JavaScriptCore/jit/JIT.h
@@ -235,7 +235,7 @@ namespace JSC {
static void patchGetByIdSelf(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress);
static void patchPutByIdReplace(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress, bool direct);
- static void patchMethodCallProto(CodeBlock* codeblock, MethodCallLinkInfo&, JSFunction*, Structure*, JSObject*, ReturnAddressPtr);
+ static void patchMethodCallProto(JSGlobalData&, CodeBlock* codeblock, MethodCallLinkInfo&, JSFunction*, Structure*, JSObject*, ReturnAddressPtr);
static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, ReturnAddressPtr returnAddress)
{
@@ -311,7 +311,7 @@ namespace JSC {
void emitStoreInt32(unsigned index, RegisterID payload, bool indexIsInt32 = false);
void emitStoreInt32(unsigned index, TrustedImm32 payload, bool indexIsInt32 = false);
void emitStoreCell(unsigned index, RegisterID payload, bool indexIsCell = false);
- void emitStoreBool(unsigned index, RegisterID tag, bool indexIsBool = false);
+ void emitStoreBool(unsigned index, RegisterID payload, bool indexIsBool = false);
void emitStoreDouble(unsigned index, FPRegisterID value);
bool isLabeled(unsigned bytecodeOffset);
@@ -473,6 +473,48 @@ namespace JSC {
static const int patchOffsetMethodCheckProtoStruct = 52;
static const int patchOffsetMethodCheckPutFunction = 84;
#endif
+#elif CPU(SH4)
+ // These architecture specific value are used to enable patching - see comment on op_put_by_id.
+ static const int patchOffsetGetByIdStructure = 6;
+ static const int patchOffsetPutByIdPropertyMapOffset = 24;
+ static const int patchOffsetPutByIdStructure = 6;
+ // These architecture specific value are used to enable patching - see comment on op_get_by_id.
+ static const int patchOffsetGetByIdBranchToSlowCase = 10;
+ static const int patchOffsetGetByIdPropertyMapOffset = 24;
+ static const int patchOffsetGetByIdPutResult = 32;
+
+ // sequenceOpCall
+ static const int sequenceOpCallInstructionSpace = 12;
+ static const int sequenceOpCallConstantSpace = 2;
+ // sequenceMethodCheck
+ static const int sequenceMethodCheckInstructionSpace = 40;
+ static const int sequenceMethodCheckConstantSpace = 6;
+ // sequenceGetByIdHotPath
+ static const int sequenceGetByIdHotPathInstructionSpace = 36;
+ static const int sequenceGetByIdHotPathConstantSpace = 5;
+ // sequenceGetByIdSlowCase
+ static const int sequenceGetByIdSlowCaseInstructionSpace = 26;
+ static const int sequenceGetByIdSlowCaseConstantSpace = 2;
+ // sequencePutById
+ static const int sequencePutByIdInstructionSpace = 36;
+ static const int sequencePutByIdConstantSpace = 5;
+
+ static const int patchOffsetGetByIdPropertyMapOffset1 = 20;
+ static const int patchOffsetGetByIdPropertyMapOffset2 = 26;
+
+ static const int patchOffsetPutByIdPropertyMapOffset1 = 20;
+ static const int patchOffsetPutByIdPropertyMapOffset2 = 26;
+
+#if ENABLE(OPCODE_SAMPLING)
+ static const int patchOffsetGetByIdSlowCaseCall = 0; // FIMXE
+#else
+ static const int patchOffsetGetByIdSlowCaseCall = 22;
+#endif
+ static const int patchOffsetOpCallCompareToJump = 4;
+
+ static const int patchOffsetMethodCheckProtoObj = 12;
+ static const int patchOffsetMethodCheckProtoStruct = 20;
+ static const int patchOffsetMethodCheckPutFunction = 32;
#else
#error "JSVALUE32_64 not supported on this platform."
#endif
@@ -665,14 +707,16 @@ namespace JSC {
#if (defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL)
#define BEGIN_UNINTERRUPTED_SEQUENCE(name) do { beginUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace); } while (false)
-#define END_UNINTERRUPTED_SEQUENCE(name) do { endUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace); } while (false)
+#define END_UNINTERRUPTED_SEQUENCE_FOR_PUT(name, dst) do { endUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace, dst); } while (false)
+#define END_UNINTERRUPTED_SEQUENCE(name) END_UNINTERRUPTED_SEQUENCE_FOR_PUT(name, 0)
void beginUninterruptedSequence(int, int);
- void endUninterruptedSequence(int, int);
+ void endUninterruptedSequence(int, int, int);
#else
#define BEGIN_UNINTERRUPTED_SEQUENCE(name) do { beginUninterruptedSequence(); } while (false)
#define END_UNINTERRUPTED_SEQUENCE(name) do { endUninterruptedSequence(); } while (false)
+#define END_UNINTERRUPTED_SEQUENCE_FOR_PUT(name, dst) do { endUninterruptedSequence(); } while (false)
#endif
void emit_op_add(Instruction*);
diff --git a/Source/JavaScriptCore/jit/JITArithmetic.cpp b/Source/JavaScriptCore/jit/JITArithmetic.cpp
index edf2290..734cc1d 100644
--- a/Source/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/Source/JavaScriptCore/jit/JITArithmetic.cpp
@@ -966,7 +966,7 @@ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned, unsigned op1, unsign
void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned result, unsigned op1, unsigned op2, OperandTypes types, bool op1HasImmediateIntFastCase, bool op2HasImmediateIntFastCase)
{
// We assume that subtracting TagTypeNumber is equivalent to adding DoubleEncodeOffset.
- COMPILE_ASSERT(((JSImmediate::TagTypeNumber + JSImmediate::DoubleEncodeOffset) == 0), TagTypeNumber_PLUS_DoubleEncodeOffset_EQUALS_0);
+ COMPILE_ASSERT(((TagTypeNumber + DoubleEncodeOffset) == 0), TagTypeNumber_PLUS_DoubleEncodeOffset_EQUALS_0);
Jump notImm1;
Jump notImm2;
diff --git a/Source/JavaScriptCore/jit/JITInlineMethods.h b/Source/JavaScriptCore/jit/JITInlineMethods.h
index 16c2335..dabfdd2 100644
--- a/Source/JavaScriptCore/jit/JITInlineMethods.h
+++ b/Source/JavaScriptCore/jit/JITInlineMethods.h
@@ -123,6 +123,13 @@ ALWAYS_INLINE void JIT::beginUninterruptedSequence(int insnSpace, int constSpace
ensureSpace(insnSpace, constSpace);
+#elif CPU(SH4)
+#ifndef NDEBUG
+ insnSpace += sizeof(SH4Word);
+ constSpace += sizeof(uint64_t);
+#endif
+
+ m_assembler.ensureSpace(insnSpace + m_assembler.maxInstructionSize + 2, constSpace + 8);
#endif
#if defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL
@@ -133,8 +140,9 @@ ALWAYS_INLINE void JIT::beginUninterruptedSequence(int insnSpace, int constSpace
#endif
}
-ALWAYS_INLINE void JIT::endUninterruptedSequence(int insnSpace, int constSpace)
+ALWAYS_INLINE void JIT::endUninterruptedSequence(int insnSpace, int constSpace, int dst)
{
+ UNUSED_PARAM(dst);
#if defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL
/* There are several cases when the uninterrupted sequence is larger than
* maximum required offset for pathing the same sequence. Eg.: if in a
@@ -143,6 +151,15 @@ ALWAYS_INLINE void JIT::endUninterruptedSequence(int insnSpace, int constSpace)
* calculation of length of uninterrupted sequence. So, the insnSpace and
* constSpace should be upper limit instead of hard limit.
*/
+#if CPU(SH4)
+ if ((dst > 15) || (dst < -16)) {
+ insnSpace += 8;
+ constSpace += 2;
+ }
+
+ if (((dst >= -16) && (dst < 0)) || ((dst > 7) && (dst <= 15)))
+ insnSpace += 8;
+#endif
ASSERT(differenceBetween(m_uninterruptedInstructionSequenceBegin, label()) <= insnSpace);
ASSERT(sizeOfConstantPool() - m_uninterruptedConstantSequenceBegin <= constSpace);
#endif
@@ -167,6 +184,22 @@ ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address)
{
loadPtr(address, linkRegister);
}
+#elif CPU(SH4)
+
+ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg)
+{
+ m_assembler.stspr(reg);
+}
+
+ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(RegisterID reg)
+{
+ m_assembler.ldspr(reg);
+}
+
+ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address)
+{
+ loadPtrLinkReg(address);
+}
#elif CPU(MIPS)
@@ -217,6 +250,8 @@ ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline()
addPtr(TrustedImm32(sizeof(void*)), stackPointerRegister, firstArgumentRegister);
#elif CPU(ARM)
move(stackPointerRegister, firstArgumentRegister);
+#elif CPU(SH4)
+ move(stackPointerRegister, firstArgumentRegister);
#endif
// In the trampoline on x86-64, the first argument register is not overwritten.
}
@@ -453,11 +488,11 @@ inline void JIT::emitStoreCell(unsigned index, RegisterID payload, bool indexIsC
store32(TrustedImm32(JSValue::CellTag), tagFor(index, callFrameRegister));
}
-inline void JIT::emitStoreBool(unsigned index, RegisterID tag, bool indexIsBool)
+inline void JIT::emitStoreBool(unsigned index, RegisterID payload, bool indexIsBool)
{
+ store32(payload, payloadFor(index, callFrameRegister));
if (!indexIsBool)
- store32(TrustedImm32(0), payloadFor(index, callFrameRegister));
- store32(tag, tagFor(index, callFrameRegister));
+ store32(TrustedImm32(JSValue::BooleanTag), tagFor(index, callFrameRegister));
}
inline void JIT::emitStoreDouble(unsigned index, FPRegisterID value)
@@ -674,7 +709,7 @@ ALWAYS_INLINE JIT::Jump JIT::emitJumpIfJSCell(RegisterID reg)
#if USE(JSVALUE64)
return branchTestPtr(Zero, reg, tagMaskRegister);
#else
- return branchTest32(Zero, reg, TrustedImm32(JSImmediate::TagMask));
+ return branchTest32(Zero, reg, TrustedImm32(TagMask));
#endif
}
@@ -695,7 +730,7 @@ ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotJSCell(RegisterID reg)
#if USE(JSVALUE64)
return branchTestPtr(NonZero, reg, tagMaskRegister);
#else
- return branchTest32(NonZero, reg, TrustedImm32(JSImmediate::TagMask));
+ return branchTest32(NonZero, reg, TrustedImm32(TagMask));
#endif
}
@@ -736,7 +771,7 @@ ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateInteger(RegisterID reg)
#if USE(JSVALUE64)
return branchPtr(AboveOrEqual, reg, tagTypeNumberRegister);
#else
- return branchTest32(NonZero, reg, TrustedImm32(JSImmediate::TagTypeNumber));
+ return branchTest32(NonZero, reg, TrustedImm32(TagTypeNumber));
#endif
}
@@ -745,7 +780,7 @@ ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateInteger(RegisterID reg)
#if USE(JSVALUE64)
return branchPtr(Below, reg, tagTypeNumberRegister);
#else
- return branchTest32(Zero, reg, TrustedImm32(JSImmediate::TagTypeNumber));
+ return branchTest32(Zero, reg, TrustedImm32(TagTypeNumber));
#endif
}
@@ -774,12 +809,12 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateNumber(RegisterID reg)
#if USE(JSVALUE32_64)
ALWAYS_INLINE void JIT::emitFastArithDeTagImmediate(RegisterID reg)
{
- subPtr(TrustedImm32(JSImmediate::TagTypeNumber), reg);
+ subPtr(TrustedImm32(TagTypeNumber), reg);
}
ALWAYS_INLINE JIT::Jump JIT::emitFastArithDeTagImmediateJumpIfZero(RegisterID reg)
{
- return branchSubPtr(Zero, TrustedImm32(JSImmediate::TagTypeNumber), reg);
+ return branchSubPtr(Zero, TrustedImm32(TagTypeNumber), reg);
}
#endif
@@ -790,7 +825,7 @@ ALWAYS_INLINE void JIT::emitFastArithReTagImmediate(RegisterID src, RegisterID d
#else
if (src != dest)
move(src, dest);
- addPtr(TrustedImm32(JSImmediate::TagTypeNumber), dest);
+ addPtr(TrustedImm32(TagTypeNumber), dest);
#endif
}
@@ -810,8 +845,7 @@ ALWAYS_INLINE void JIT::emitFastArithIntToImmNoCheck(RegisterID src, RegisterID
ALWAYS_INLINE void JIT::emitTagAsBoolImmediate(RegisterID reg)
{
- lshift32(TrustedImm32(JSImmediate::ExtendedPayloadShift), reg);
- or32(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), reg);
+ or32(TrustedImm32(static_cast<int32_t>(ValueFalse)), reg);
}
#endif // USE(JSVALUE32_64)
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index daceea6..53bc1df 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -57,7 +57,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
// Checks out okay! - get the length from the Ustring.
load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_length)), regT0);
- Jump string_failureCases3 = branch32(Above, regT0, TrustedImm32(JSImmediate::maxImmediateInt));
+ Jump string_failureCases3 = branch32(LessThan, regT0, TrustedImm32(0));
// regT0 contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
emitFastArithIntToImmNoCheck(regT0, regT0);
@@ -695,9 +695,14 @@ void JIT::emitSlow_op_resolve_global(Instruction* currentInstruction, Vector<Slo
void JIT::emit_op_not(Instruction* currentInstruction)
{
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))));
- xorPtr(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue)), regT0);
+
+ // Invert against JSValue(false); if the value was tagged as a boolean, then all bits will be
+ // clear other than the low bit (which will be 0 or 1 for false or true inputs respectively).
+ // Then invert against JSValue(true), which will add the tag back in, and flip the low bit.
+ xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), regT0);
+ addSlowCase(branchTestPtr(NonZero, regT0, TrustedImm32(static_cast<int32_t>(~1))));
+ xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), regT0);
+
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
@@ -731,7 +736,7 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction)
// Now handle the immediate cases - undefined & null
isImmediate.link(this);
- andPtr(TrustedImm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
+ andPtr(TrustedImm32(~TagBitUndefined), regT0);
addJump(branchPtr(Equal, regT0, TrustedImmPtr(JSValue::encode(jsNull()))), target);
wasNotImmediate.link(this);
@@ -752,7 +757,7 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
// Now handle the immediate cases - undefined & null
isImmediate.link(this);
- andPtr(TrustedImm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
+ andPtr(TrustedImm32(~TagBitUndefined), regT0);
addJump(branchPtr(NotEqual, regT0, TrustedImmPtr(JSValue::encode(jsNull()))), target);
wasNotImmediate.link(this);
@@ -909,8 +914,8 @@ void JIT::emit_op_get_pnames(Instruction* currentInstruction)
isNotObject.link(this);
move(regT0, regT1);
- and32(TrustedImm32(~JSImmediate::ExtendedTagBitUndefined), regT1);
- addJump(branch32(Equal, regT1, TrustedImm32(JSImmediate::FullTagTypeNull)), breakTarget);
+ and32(TrustedImm32(~TagBitUndefined), regT1);
+ addJump(branch32(Equal, regT1, TrustedImm32(ValueNull)), breakTarget);
JITStubCall toObjectStubCall(this, cti_to_object);
toObjectStubCall.addArgument(regT0);
@@ -1163,8 +1168,8 @@ void JIT::emit_op_eq_null(Instruction* currentInstruction)
isImmediate.link(this);
- andPtr(TrustedImm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
- setPtr(Equal, regT0, TrustedImm32(JSImmediate::FullTagTypeNull), regT0);
+ andPtr(TrustedImm32(~TagBitUndefined), regT0);
+ setPtr(Equal, regT0, TrustedImm32(ValueNull), regT0);
wasNotImmediate.link(this);
@@ -1188,8 +1193,8 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
isImmediate.link(this);
- andPtr(TrustedImm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
- setPtr(NotEqual, regT0, TrustedImm32(JSImmediate::FullTagTypeNull), regT0);
+ andPtr(TrustedImm32(~TagBitUndefined), regT0);
+ setPtr(NotEqual, regT0, TrustedImm32(ValueNull), regT0);
wasNotImmediate.link(this);
@@ -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)
{
linkSlowCase(iter);
- xorPtr(TrustedImm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0);
+ xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), regT0);
JITStubCall stubCall(this, cti_op_not);
stubCall.addArgument(regT0);
stubCall.call(currentInstruction[1].u.operand);
diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
index bc0b2cb..edce21c 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -245,7 +245,26 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
call(Address(regT2, executableOffsetToFunction));
restoreReturnAddressBeforeReturn(regT3);
+#elif CPU(SH4)
+ // Load caller frame's scope chain into this callframe so that whatever we call can
+ // get to its global data.
+ emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2);
+ emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2);
+ emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+
+ preserveReturnAddressAfterCall(regT3); // Callee preserved
+ emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
+
+ // Calling convention: f(r0 == regT4, r1 == regT5, ...);
+ // Host function signature: f(ExecState*);
+ move(callFrameRegister, regT4);
+
+ emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT5);
+ move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
+ loadPtr(Address(regT5, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
+ call(Address(regT2, executableOffsetToFunction), regT0);
+ restoreReturnAddressBeforeReturn(regT3);
#elif CPU(MIPS)
// Load caller frame's scope chain into this callframe so that whatever we call can
// get to its global data.
@@ -394,7 +413,28 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa
addPtr(TrustedImm32(16), stackPointerRegister);
restoreReturnAddressBeforeReturn(regT3);
+#elif CPU(SH4)
+ // Load caller frame's scope chain into this callframe so that whatever we call can
+ // get to its global data.
+ emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2);
+ emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2);
+ emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+ preserveReturnAddressAfterCall(regT3); // Callee preserved
+ emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
+
+ // Calling convention: f(r0 == regT4, r1 == regT5, ...);
+ // Host function signature: f(ExecState*);
+ move(callFrameRegister, regT4);
+
+ emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT5);
+ move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
+ loadPtr(Address(regT5, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
+
+ // call the function
+ nativeCall = call();
+
+ restoreReturnAddressBeforeReturn(regT3);
#elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
#error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform."
#else
@@ -553,7 +593,7 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
// Optimistically load the result true, and start looping.
// Initially, regT1 still contains proto and regT2 still contains value.
// As we loop regT2 will be updated with its prototype, recursively walking the prototype chain.
- move(TrustedImm32(JSValue::TrueTag), regT0);
+ move(TrustedImm32(1), regT0);
Label loop(this);
// Load the prototype of the cell in regT2. If this is equal to regT1 - WIN!
@@ -564,7 +604,7 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
branchTest32(NonZero, regT2).linkTo(loop, this);
// We get here either by dropping out of the loop, or if value was not an Object. Result is false.
- move(TrustedImm32(JSValue::FalseTag), regT0);
+ move(TrustedImm32(0), regT0);
// isInstance jumps right down to here, to skip setting the result to false (it has already set true).
isInstance.link(this);
@@ -829,9 +869,9 @@ void JIT::emit_op_not(Instruction* currentInstruction)
emitLoadTag(src, regT0);
- xor32(TrustedImm32(JSValue::FalseTag), regT0);
- addSlowCase(branchTest32(NonZero, regT0, TrustedImm32(~1)));
- xor32(TrustedImm32(JSValue::TrueTag), regT0);
+ emitLoad(src, regT1, regT0);
+ addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::BooleanTag)));
+ xor32(TrustedImm32(1), regT0);
emitStoreBool(dst, regT0, (dst == src));
}
@@ -855,25 +895,9 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction)
emitLoad(cond, regT1, regT0);
- Jump isTrue = branch32(Equal, regT1, TrustedImm32(JSValue::TrueTag));
- addJump(branch32(Equal, regT1, TrustedImm32(JSValue::FalseTag)), target);
-
- Jump isNotInteger = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag));
- Jump isTrue2 = branch32(NotEqual, regT0, TrustedImm32(0));
- addJump(jump(), target);
-
- if (supportsFloatingPoint()) {
- isNotInteger.link(this);
-
- addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)));
-
- emitLoadDouble(cond, fpRegT0);
- addJump(branchDoubleZeroOrNaN(fpRegT0, fpRegT1), target);
- } else
- addSlowCase(isNotInteger);
-
- isTrue.link(this);
- isTrue2.link(this);
+ ASSERT((JSValue::BooleanTag + 1 == JSValue::Int32Tag) && !(JSValue::Int32Tag + 1));
+ addSlowCase(branch32(Below, regT1, TrustedImm32(JSValue::BooleanTag)));
+ addJump(branchTest32(Zero, regT0), target);
}
void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -882,6 +906,18 @@ void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEnt
unsigned target = currentInstruction[2].u.operand;
linkSlowCase(iter);
+
+ if (supportsFloatingPoint()) {
+ // regT1 contains the tag from the hot path.
+ Jump notNumber = branch32(Above, regT1, Imm32(JSValue::LowestTag));
+
+ emitLoadDouble(cond, fpRegT0);
+ emitJumpSlowToHot(branchDoubleZeroOrNaN(fpRegT0, fpRegT1), target);
+ emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jfalse));
+
+ notNumber.link(this);
+ }
+
JITStubCall stubCall(this, cti_op_jtrue);
stubCall.addArgument(cond);
stubCall.call();
@@ -895,25 +931,9 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction)
emitLoad(cond, regT1, regT0);
- Jump isFalse = branch32(Equal, regT1, TrustedImm32(JSValue::FalseTag));
- addJump(branch32(Equal, regT1, TrustedImm32(JSValue::TrueTag)), target);
-
- Jump isNotInteger = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag));
- Jump isFalse2 = branch32(Equal, regT0, TrustedImm32(0));
- addJump(jump(), target);
-
- if (supportsFloatingPoint()) {
- isNotInteger.link(this);
-
- addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)));
-
- emitLoadDouble(cond, fpRegT0);
- addJump(branchDoubleNonZero(fpRegT0, fpRegT1), target);
- } else
- addSlowCase(isNotInteger);
-
- isFalse.link(this);
- isFalse2.link(this);
+ ASSERT((JSValue::BooleanTag + 1 == JSValue::Int32Tag) && !(JSValue::Int32Tag + 1));
+ addSlowCase(branch32(Below, regT1, TrustedImm32(JSValue::BooleanTag)));
+ addJump(branchTest32(NonZero, regT0), target);
}
void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -922,6 +942,18 @@ void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntr
unsigned target = currentInstruction[2].u.operand;
linkSlowCase(iter);
+
+ if (supportsFloatingPoint()) {
+ // regT1 contains the tag from the hot path.
+ Jump notNumber = branch32(Above, regT1, Imm32(JSValue::LowestTag));
+
+ emitLoadDouble(cond, fpRegT0);
+ emitJumpSlowToHot(branchDoubleNonZero(fpRegT0, fpRegT1), target);
+ emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jtrue));
+
+ notNumber.link(this);
+ }
+
JITStubCall stubCall(this, cti_op_jtrue);
stubCall.addArgument(cond);
stubCall.call();
@@ -946,8 +978,9 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction)
// Now handle the immediate cases - undefined & null
isImmediate.link(this);
- ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && !(JSValue::NullTag + 1));
- addJump(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::UndefinedTag)), target);
+ ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && (JSValue::NullTag & 0x1));
+ or32(TrustedImm32(1), regT1);
+ addJump(branch32(Equal, regT1, TrustedImm32(JSValue::NullTag)), target);
wasNotImmediate.link(this);
}
@@ -970,8 +1003,9 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
// Now handle the immediate cases - undefined & null
isImmediate.link(this);
- ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && !(JSValue::NullTag + 1));
- addJump(branch32(Below, regT1, TrustedImm32(JSValue::UndefinedTag)), target);
+ ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && (JSValue::NullTag & 0x1));
+ or32(TrustedImm32(1), regT1);
+ addJump(branch32(NotEqual, regT1, TrustedImm32(JSValue::NullTag)), target);
wasNotImmediate.link(this);
}
@@ -1012,8 +1046,7 @@ void JIT::emit_op_eq(Instruction* currentInstruction)
addSlowCase(branch32(Equal, regT1, TrustedImm32(JSValue::CellTag)));
addSlowCase(branch32(Below, regT1, TrustedImm32(JSValue::LowestTag)));
- set8Compare32(Equal, regT0, regT2, regT0);
- or32(TrustedImm32(JSValue::FalseTag), regT0);
+ set32Compare32(Equal, regT0, regT2, regT0);
emitStoreBool(dst, regT0);
}
@@ -1049,7 +1082,6 @@ void JIT::emitSlow_op_eq(Instruction* currentInstruction, Vector<SlowCaseEntry>:
stubCallEq.call(regT0);
storeResult.link(this);
- or32(TrustedImm32(JSValue::FalseTag), regT0);
emitStoreBool(dst, regT0);
}
@@ -1064,8 +1096,7 @@ void JIT::emit_op_neq(Instruction* currentInstruction)
addSlowCase(branch32(Equal, regT1, TrustedImm32(JSValue::CellTag)));
addSlowCase(branch32(Below, regT1, TrustedImm32(JSValue::LowestTag)));
- set8Compare32(NotEqual, regT0, regT2, regT0);
- or32(TrustedImm32(JSValue::FalseTag), regT0);
+ set32Compare32(NotEqual, regT0, regT2, regT0);
emitStoreBool(dst, regT0);
}
@@ -1100,7 +1131,6 @@ void JIT::emitSlow_op_neq(Instruction* currentInstruction, Vector<SlowCaseEntry>
storeResult.link(this);
xor32(TrustedImm32(0x1), regT0);
- or32(TrustedImm32(JSValue::FalseTag), regT0);
emitStoreBool(dst, regT0);
}
@@ -1121,11 +1151,9 @@ void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqTy
addSlowCase(branch32(AboveOrEqual, regT2, TrustedImm32(JSValue::CellTag)));
if (type == OpStrictEq)
- set8Compare32(Equal, regT0, regT1, regT0);
+ set32Compare32(Equal, regT0, regT1, regT0);
else
- set8Compare32(NotEqual, regT0, regT1, regT0);
-
- or32(TrustedImm32(JSValue::FalseTag), regT0);
+ set32Compare32(NotEqual, regT0, regT1, regT0);
emitStoreBool(dst, regT0);
}
@@ -1185,14 +1213,12 @@ void JIT::emit_op_eq_null(Instruction* currentInstruction)
isImmediate.link(this);
- set8Compare32(Equal, regT1, TrustedImm32(JSValue::NullTag), regT2);
- set8Compare32(Equal, regT1, TrustedImm32(JSValue::UndefinedTag), regT1);
+ set32Compare32(Equal, regT1, TrustedImm32(JSValue::NullTag), regT2);
+ set32Compare32(Equal, regT1, TrustedImm32(JSValue::UndefinedTag), regT1);
or32(regT2, regT1);
wasNotImmediate.link(this);
- or32(TrustedImm32(JSValue::FalseTag), regT1);
-
emitStoreBool(dst, regT1);
}
@@ -1211,14 +1237,12 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
isImmediate.link(this);
- set8Compare32(NotEqual, regT1, TrustedImm32(JSValue::NullTag), regT2);
- set8Compare32(NotEqual, regT1, TrustedImm32(JSValue::UndefinedTag), regT1);
+ set32Compare32(NotEqual, regT1, TrustedImm32(JSValue::NullTag), regT2);
+ set32Compare32(NotEqual, regT1, TrustedImm32(JSValue::UndefinedTag), regT1);
and32(regT2, regT1);
wasNotImmediate.link(this);
- or32(TrustedImm32(JSValue::FalseTag), regT1);
-
emitStoreBool(dst, regT1);
}
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
index 68f8dda..a1f1fe6 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -581,7 +581,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
// ecx = baseObject->m_structure
if (!direct) {
- for (RefPtr<Structure>* it = chain->head(); *it; ++it)
+ for (WriteBarrier<Structure>* it = chain->head(); *it; ++it)
testPrototype((*it)->storedPrototype(), failureCases);
}
@@ -606,11 +606,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
restoreReturnAddressBeforeReturn(regT3);
}
- // Assumes m_refCount can be decremented easily, refcount decrement is safe as
- // codeblock should ensure oldStructure->m_refCount > 0
- sub32(TrustedImm32(1), AbsoluteAddress(oldStructure->addressOfCount()));
- add32(TrustedImm32(1), AbsoluteAddress(newStructure->addressOfCount()));
- storePtr(TrustedImmPtr(newStructure), Address(regT0, JSCell::structureOffset()));
+ storePtrWithWriteBarrier(TrustedImmPtr(newStructure), regT0, Address(regT0, JSCell::structureOffset()));
// write the value
compilePutDirectOffset(regT0, regT1, newStructure, cachedOffset);
@@ -652,17 +648,15 @@ void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, St
repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetGetByIdPropertyMapOffset), offset);
}
-void JIT::patchMethodCallProto(CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, JSFunction* callee, Structure* structure, JSObject* proto, ReturnAddressPtr returnAddress)
+void JIT::patchMethodCallProto(JSGlobalData& globalData, CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, JSFunction* callee, Structure* structure, JSObject* proto, ReturnAddressPtr returnAddress)
{
RepatchBuffer repatchBuffer(codeBlock);
ASSERT(!methodCallLinkInfo.cachedStructure);
- methodCallLinkInfo.cachedStructure = structure;
- structure->ref();
+ methodCallLinkInfo.cachedStructure.set(globalData, codeBlock->ownerExecutable(), structure);
Structure* prototypeStructure = proto->structure();
- methodCallLinkInfo.cachedPrototypeStructure = prototypeStructure;
- prototypeStructure->ref();
+ methodCallLinkInfo.cachedPrototypeStructure.set(globalData, codeBlock->ownerExecutable(), prototypeStructure);
repatchBuffer.repatch(methodCallLinkInfo.structureLabel, structure);
repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckProtoObj), proto);
@@ -697,7 +691,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
// Checks out okay! - get the length from the storage
loadPtr(Address(regT0, JSArray::storageOffset()), regT3);
load32(Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length)), regT2);
- Jump failureCases2 = branch32(Above, regT2, TrustedImm32(JSImmediate::maxImmediateInt));
+ Jump failureCases2 = branch32(LessThan, regT2, TrustedImm32(0));
emitFastArithIntToImmNoCheck(regT2, regT0);
Jump success = jump();
@@ -735,7 +729,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
Jump failureCases1 = checkStructure(regT0, structure);
// Check the prototype object's Structure had not changed.
- Structure* const * prototypeStructureAddress = protoObject->addressOfStructure();
+ const void* prototypeStructureAddress = protoObject->addressOfStructure();
#if CPU(X86_64)
move(TrustedImmPtr(prototypeStructure), regT3);
Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
@@ -839,8 +833,7 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic
CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
- structure->ref();
- polymorphicStructures->list[currentIndex].set(entryLabel, structure);
+ polymorphicStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), entryLabel, structure);
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
@@ -858,7 +851,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
Jump failureCases1 = checkStructure(regT0, structure);
// Check the prototype object's Structure had not changed.
- Structure* const * prototypeStructureAddress = protoObject->addressOfStructure();
+ const void* prototypeStructureAddress = protoObject->addressOfStructure();
#if CPU(X86_64)
move(TrustedImmPtr(prototypeStructure), regT3);
Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
@@ -907,10 +900,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
-
- structure->ref();
- prototypeStructure->ref();
- prototypeStructures->list[currentIndex].set(entryLabel, structure, prototypeStructure);
+ prototypeStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), entryLabel, structure, prototypeStructure);
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
@@ -928,7 +918,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
bucketsOfFail.append(baseObjectCheck);
Structure* currStructure = structure;
- RefPtr<Structure>* it = chain->head();
+ WriteBarrier<Structure>* it = chain->head();
JSObject* protoObject = 0;
for (unsigned i = 0; i < count; ++i, ++it) {
protoObject = asObject(currStructure->prototypeForLookup(callFrame));
@@ -978,7 +968,6 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
// Track the stub we have created so that it will be deleted later.
- structure->ref();
prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), entryLabel, structure, chain);
// Finally patch the jump to slow case back in the hot path to jump here instead.
@@ -997,7 +986,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
bucketsOfFail.append(checkStructure(regT0, structure));
Structure* currStructure = structure;
- RefPtr<Structure>* it = chain->head();
+ WriteBarrier<Structure>* it = chain->head();
JSObject* protoObject = 0;
for (unsigned i = 0; i < count; ++i, ++it) {
protoObject = asObject(currStructure->prototypeForLookup(callFrame));
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
index 2a47e5c..d0c3688 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
@@ -475,7 +475,7 @@ void JIT::compileGetByIdSlowCase(int dst, int base, Identifier* ident, Vector<Sl
stubCall.addArgument(TrustedImmPtr(ident));
Call call = stubCall.call(dst);
- END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase);
+ END_UNINTERRUPTED_SEQUENCE_FOR_PUT(sequenceGetByIdSlowCase, dst);
ASSERT_JIT_OFFSET(differenceBetween(coldPathBegin, call), patchOffsetGetByIdSlowCaseCall);
@@ -597,7 +597,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
if (!direct) {
// Verify that nothing in the prototype chain has a setter for this property.
- for (RefPtr<Structure>* it = chain->head(); *it; ++it)
+ for (WriteBarrier<Structure>* it = chain->head(); *it; ++it)
testPrototype((*it)->storedPrototype(), failureCases);
}
@@ -619,12 +619,10 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
restoreReturnAddressBeforeReturn(regT3);
}
+
+ storePtrWithWriteBarrier(TrustedImmPtr(newStructure), regT0, Address(regT0, JSCell::structureOffset()));
- sub32(TrustedImm32(1), AbsoluteAddress(oldStructure->addressOfCount()));
- add32(TrustedImm32(1), AbsoluteAddress(newStructure->addressOfCount()));
- storePtr(TrustedImmPtr(newStructure), Address(regT0, JSCell::structureOffset()));
-
-#if CPU(MIPS)
+#if CPU(MIPS) || CPU(SH4)
// For MIPS, we don't add sizeof(void*) to the stack offset.
load32(Address(stackPointerRegister, OBJECT_OFFSETOF(JITStackFrame, args[2]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT3);
load32(Address(stackPointerRegister, OBJECT_OFFSETOF(JITStackFrame, args[2]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT2);
@@ -674,17 +672,14 @@ void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, St
repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetGetByIdPropertyMapOffset2), offset + OBJECT_OFFSETOF(JSValue, u.asBits.tag)); // tag
}
-void JIT::patchMethodCallProto(CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, JSFunction* callee, Structure* structure, JSObject* proto, ReturnAddressPtr returnAddress)
+void JIT::patchMethodCallProto(JSGlobalData& globalData, CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, JSFunction* callee, Structure* structure, JSObject* proto, ReturnAddressPtr returnAddress)
{
RepatchBuffer repatchBuffer(codeBlock);
ASSERT(!methodCallLinkInfo.cachedStructure);
- methodCallLinkInfo.cachedStructure = structure;
- structure->ref();
-
+ methodCallLinkInfo.cachedStructure.set(globalData, codeBlock->ownerExecutable(), structure);
Structure* prototypeStructure = proto->structure();
- methodCallLinkInfo.cachedPrototypeStructure = prototypeStructure;
- prototypeStructure->ref();
+ methodCallLinkInfo.cachedPrototypeStructure.set(globalData, codeBlock->ownerExecutable(), prototypeStructure);
repatchBuffer.repatch(methodCallLinkInfo.structureLabel, structure);
repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckProtoObj), proto);
@@ -762,7 +757,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
Jump failureCases1 = checkStructure(regT0, structure);
// Check the prototype object's Structure had not changed.
- Structure* const * prototypeStructureAddress = protoObject->addressOfStructure();
+ const void* prototypeStructureAddress = protoObject->addressOfStructure();
#if CPU(X86_64)
move(TrustedImmPtr(prototypeStructure), regT3);
Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
@@ -867,9 +862,8 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
-
- structure->ref();
- polymorphicStructures->list[currentIndex].set(entryLabel, structure);
+
+ polymorphicStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), entryLabel, structure);
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
@@ -889,7 +883,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
Jump failureCases1 = checkStructure(regT0, structure);
// Check the prototype object's Structure had not changed.
- Structure* const * prototypeStructureAddress = protoObject->addressOfStructure();
+ const void* prototypeStructureAddress = protoObject->addressOfStructure();
#if CPU(X86_64)
move(TrustedImmPtr(prototypeStructure), regT3);
Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
@@ -935,10 +929,8 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
-
- structure->ref();
- prototypeStructure->ref();
- prototypeStructures->list[currentIndex].set(entryLabel, structure, prototypeStructure);
+
+ prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), entryLabel, structure, prototypeStructure);
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
@@ -957,7 +949,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
bucketsOfFail.append(checkStructure(regT0, structure));
Structure* currStructure = structure;
- RefPtr<Structure>* it = chain->head();
+ WriteBarrier<Structure>* it = chain->head();
JSObject* protoObject = 0;
for (unsigned i = 0; i < count; ++i, ++it) {
protoObject = asObject(currStructure->prototypeForLookup(callFrame));
@@ -1006,7 +998,6 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
// Track the stub we have created so that it will be deleted later.
- structure->ref();
prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), entryLabel, structure, chain);
// Finally patch the jump to slow case back in the hot path to jump here instead.
@@ -1026,7 +1017,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
bucketsOfFail.append(checkStructure(regT0, structure));
Structure* currStructure = structure;
- RefPtr<Structure>* it = chain->head();
+ WriteBarrier<Structure>* it = chain->head();
JSObject* protoObject = 0;
for (unsigned i = 0; i < count; ++i, ++it) {
protoObject = asObject(currStructure->prototypeForLookup(callFrame));
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index e52c7c8..953bd11 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -40,7 +40,7 @@
#include "Debugger.h"
#include "ExceptionHelpers.h"
#include "GetterSetter.h"
-#include "Global.h"
+#include "Strong.h"
#include "JIT.h"
#include "JSActivation.h"
#include "JSArray.h"
@@ -67,7 +67,7 @@ using namespace std;
namespace JSC {
-#if OS(DARWIN) || OS(WINDOWS)
+#if OS(DARWIN) || (OS(WINDOWS) && CPU(X86))
#define SYMBOL_STRING(name) "_" #name
#else
#define SYMBOL_STRING(name) #name
@@ -81,7 +81,7 @@ namespace JSC {
#if (OS(LINUX) || OS(FREEBSD)) && CPU(X86_64)
#define SYMBOL_STRING_RELOCATION(name) #name "@plt"
-#elif OS(DARWIN)
+#elif OS(DARWIN) || (CPU(X86_64) && COMPILER(MINGW) && !GCC_VERSION_AT_LEAST(4, 5, 0))
#define SYMBOL_STRING_RELOCATION(name) "_" #name
#elif CPU(X86) && COMPILER(MINGW)
#define SYMBOL_STRING_RELOCATION(name) "@" #name "@4"
@@ -314,7 +314,79 @@ extern "C" {
#define ENABLE_PROFILER_REFERENCE_OFFSET 96
#define GLOBAL_DATA_OFFSET 100
#define STACK_LENGTH 104
+#elif CPU(SH4)
+#define SYMBOL_STRING(name) #name
+/* code (r4), RegisterFile* (r5), CallFrame* (r6), JSValue* exception (r7), Profiler**(sp), JSGlobalData (sp)*/
+asm volatile (
+".text\n"
+".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+HIDE_SYMBOL(ctiTrampoline) "\n"
+SYMBOL_STRING(ctiTrampoline) ":" "\n"
+ "mov.l r7, @-r15" "\n"
+ "mov.l r6, @-r15" "\n"
+ "mov.l r5, @-r15" "\n"
+ "mov.l r8, @-r15" "\n"
+ "mov #127, r8" "\n"
+ "mov.l r14, @-r15" "\n"
+ "sts.l pr, @-r15" "\n"
+ "mov.l r13, @-r15" "\n"
+ "mov.l r11, @-r15" "\n"
+ "mov.l r10, @-r15" "\n"
+ "add #-60, r15" "\n"
+ "mov r6, r14" "\n"
+ "jsr @r4" "\n"
+ "nop" "\n"
+ "add #60, r15" "\n"
+ "mov.l @r15+,r10" "\n"
+ "mov.l @r15+,r11" "\n"
+ "mov.l @r15+,r13" "\n"
+ "lds.l @r15+,pr" "\n"
+ "mov.l @r15+,r14" "\n"
+ "mov.l @r15+,r8" "\n"
+ "add #12, r15" "\n"
+ "rts" "\n"
+ "nop" "\n"
+);
+
+asm volatile (
+".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
+SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
+ "mov.l .L2"SYMBOL_STRING(cti_vm_throw)",r0" "\n"
+ "mov r15, r4" "\n"
+ "mov.l @(r0,r12),r11" "\n"
+ "jsr @r11" "\n"
+ "nop" "\n"
+ "add #60, r15" "\n"
+ "mov.l @r15+,r10" "\n"
+ "mov.l @r15+,r11" "\n"
+ "mov.l @r15+,r13" "\n"
+ "lds.l @r15+,pr" "\n"
+ "mov.l @r15+,r14" "\n"
+ "mov.l @r15+,r8" "\n"
+ "add #12, r15" "\n"
+ "rts" "\n"
+ "nop" "\n"
+ ".align 2" "\n"
+ ".L2"SYMBOL_STRING(cti_vm_throw)":.long " SYMBOL_STRING(cti_vm_throw)"@GOT \n"
+);
+
+asm volatile (
+".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
+SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
+ "add #60, r15" "\n"
+ "mov.l @r15+,r10" "\n"
+ "mov.l @r15+,r11" "\n"
+ "mov.l @r15+,r13" "\n"
+ "lds.l @r15+,pr" "\n"
+ "mov.l @r15+,r14" "\n"
+ "mov.l @r15+,r8" "\n"
+ "add #12, r15" "\n"
+ "rts" "\n"
+ "nop" "\n"
+);
#else
#error "JIT not supported on this platform."
#endif
@@ -771,12 +843,12 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co
normalizePrototypeChain(callFrame, baseCell);
StructureChain* prototypeChain = structure->prototypeChain(callFrame);
- stubInfo->initPutByIdTransition(structure->previousID(), structure, prototypeChain);
+ stubInfo->initPutByIdTransition(callFrame->globalData(), codeBlock->ownerExecutable(), structure->previousID(), structure, prototypeChain);
JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress, direct);
return;
}
- stubInfo->initPutByIdReplace(structure);
+ stubInfo->initPutByIdReplace(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
JIT::patchPutByIdReplace(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress, direct);
}
@@ -824,7 +896,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
if (slot.slotBase() == baseValue) {
// set this up, so derefStructures can do it's job.
- stubInfo->initGetByIdSelf(structure);
+ stubInfo->initGetByIdSelf(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
if (slot.cachedPropertyType() != PropertySlot::Value)
ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_self_fail));
else
@@ -847,10 +919,10 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
// should not be treated as a dictionary.
if (slotBaseObject->structure()->isDictionary()) {
slotBaseObject->flattenDictionaryObject(callFrame->globalData());
- offset = slotBaseObject->structure()->get(propertyName);
+ offset = slotBaseObject->structure()->get(callFrame->globalData(), propertyName);
}
- stubInfo->initGetByIdProto(structure, slotBaseObject->structure());
+ stubInfo->initGetByIdProto(callFrame->globalData(), codeBlock->ownerExecutable(), structure, slotBaseObject->structure());
ASSERT(!structure->isDictionary());
ASSERT(!slotBaseObject->structure()->isDictionary());
@@ -866,7 +938,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
}
StructureChain* prototypeChain = structure->prototypeChain(callFrame);
- stubInfo->initGetByIdChain(structure, prototypeChain);
+ stubInfo->initGetByIdChain(callFrame->globalData(), codeBlock->ownerExecutable(), structure, prototypeChain);
JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, propertyName, slot, offset, returnAddress);
}
@@ -1156,6 +1228,29 @@ MSVC()
MSVC_END( END)
*/
+#elif CPU(SH4)
+#define DEFINE_STUB_FUNCTION(rtype, op) \
+ extern "C" { \
+ rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \
+ }; \
+ asm volatile( \
+ ".align 2" "\n" \
+ ".globl " SYMBOL_STRING(cti_##op) "\n" \
+ SYMBOL_STRING(cti_##op) ":" "\n" \
+ "sts pr, r11" "\n" \
+ "mov.l r11, @(0x38, r15)" "\n" \
+ "mov.l .L2"SYMBOL_STRING(JITStubThunked_##op)",r0" "\n" \
+ "mov.l @(r0,r12),r11" "\n" \
+ "jsr @r11" "\n" \
+ "nop" "\n" \
+ "mov.l @(0x38, r15), r11 " "\n" \
+ "lds r11, pr " "\n" \
+ "rts" "\n" \
+ "nop" "\n" \
+ ".align 2" "\n" \
+ ".L2"SYMBOL_STRING(JITStubThunked_##op)":.long " SYMBOL_STRING(JITStubThunked_##op)"@GOT \n" \
+ ); \
+ rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
#else
#define DEFINE_STUB_FUNCTION(rtype, op) rtype JIT_STUB cti_##op(STUB_ARGS_DECLARATION)
#endif
@@ -1465,7 +1560,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
// Check to see if the function is on the object's prototype. Patch up the code to optimize.
if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
- JIT::patchMethodCallProto(codeBlock, methodCallLinkInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS);
+ JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS);
return JSValue::encode(result);
}
@@ -1476,7 +1571,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
// for now. For now it performs a check on a special object on the global object only used for this
// purpose. The object is in no way exposed, and as such the check will always pass.
if (slot.slotBase() == baseValue) {
- JIT::patchMethodCallProto(codeBlock, methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS);
+ JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS);
return JSValue::encode(result);
}
}
@@ -1535,7 +1630,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
if (stubInfo->accessType == access_get_by_id_self) {
ASSERT(!stubInfo->stubRoutine);
- polymorphicStructureList = new PolymorphicAccessStructureList(CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure);
+ polymorphicStructureList = new PolymorphicAccessStructureList(callFrame->globalData(), codeBlock->ownerExecutable(), CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure.get());
stubInfo->initGetByIdSelfList(polymorphicStructureList, 1);
} else {
polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList;
@@ -1560,12 +1655,12 @@ static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(JSG
switch (stubInfo->accessType) {
case access_get_by_id_proto:
- prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure);
+ prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure.get(), stubInfo->u.getByIdProto.prototypeStructure.get());
stubInfo->stubRoutine = CodeLocationLabel();
stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
break;
case access_get_by_id_chain:
- prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain);
+ prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure.get(), stubInfo->u.getByIdChain.chain.get());
stubInfo->stubRoutine = CodeLocationLabel();
stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
break;
@@ -1649,7 +1744,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
// should not be treated as a dictionary.
if (slotBaseObject->structure()->isDictionary()) {
slotBaseObject->flattenDictionaryObject(callFrame->globalData());
- offset = slotBaseObject->structure()->get(propertyName);
+ offset = slotBaseObject->structure()->get(callFrame->globalData(), propertyName);
}
int listIndex;
@@ -2658,10 +2753,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_global)
JSValue result = slot.getValue(callFrame, ident);
if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
GlobalResolveInfo& globalResolveInfo = codeBlock->globalResolveInfo(globalResolveInfoIndex);
- if (globalResolveInfo.structure)
- globalResolveInfo.structure->deref();
- globalObject->structure()->ref();
- globalResolveInfo.structure = globalObject->structure();
+ globalResolveInfo.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), globalObject->structure());
globalResolveInfo.offset = slot.cachedOffset();
return JSValue::encode(result);
}
@@ -3495,7 +3587,7 @@ MacroAssemblerCodePtr JITThunks::ctiStub(JSGlobalData* globalData, ThunkGenerato
NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function)
{
- std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap->add(function, Global<NativeExecutable>(Global<NativeExecutable>::EmptyValue));
+ std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap->add(function, Strong<NativeExecutable>());
if (entry.second)
entry.first->second.set(*globalData, NativeExecutable::create(*globalData, JIT::compileCTINativeCall(globalData, m_executablePool, function), function, ctiNativeConstruct(), callHostFunctionAsConstructor));
return entry.first->second.get();
@@ -3503,7 +3595,7 @@ NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFu
NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, ThunkGenerator generator)
{
- std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap->add(function, Global<NativeExecutable>(Global<NativeExecutable>::EmptyValue));
+ std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap->add(function, Strong<NativeExecutable>());
if (entry.second) {
MacroAssemblerCodePtr code = globalData->canUseJIT() ? generator(globalData, m_executablePool.get()) : MacroAssemblerCodePtr();
entry.first->second.set(*globalData, NativeExecutable::create(*globalData, code, function, ctiNativeConstruct(), callHostFunctionAsConstructor));
diff --git a/Source/JavaScriptCore/jit/JITStubs.h b/Source/JavaScriptCore/jit/JITStubs.h
index af6e13f..7c67f6e 100644
--- a/Source/JavaScriptCore/jit/JITStubs.h
+++ b/Source/JavaScriptCore/jit/JITStubs.h
@@ -229,6 +229,27 @@ namespace JSC {
ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
};
+#elif CPU(SH4)
+ struct JITStackFrame {
+ JITStubArg padding; // Unused
+ JITStubArg args[6];
+
+ ReturnAddressPtr thunkReturnAddress;
+ void* savedR10;
+ void* savedR11;
+ void* savedR13;
+ void* savedRPR;
+ void* savedR14;
+ void* savedTimeoutReg;
+
+ RegisterFile* registerFile;
+ CallFrame* callFrame;
+ JSValue* exception;
+ Profiler** enabledProfilerReference;
+ JSGlobalData* globalData;
+
+ ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
+ };
#else
#error "JITStackFrame not defined for this platform."
#endif
@@ -254,7 +275,7 @@ namespace JSC {
extern "C" void ctiOpThrowNotCaught();
extern "C" EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, void* /*unused1*/, Profiler**, JSGlobalData*);
- template <typename T> class Global;
+ template <typename T> class Strong;
class JITThunks {
public:
@@ -283,7 +304,7 @@ namespace JSC {
private:
typedef HashMap<ThunkGenerator, MacroAssemblerCodePtr> CTIStubMap;
CTIStubMap m_ctiStubMap;
- typedef HashMap<NativeFunction, Global<NativeExecutable> > HostFunctionStubMap;
+ typedef HashMap<NativeFunction, Strong<NativeExecutable> > HostFunctionStubMap;
OwnPtr<HostFunctionStubMap> m_hostFunctionStubMap;
RefPtr<ExecutablePool> m_executablePool;
diff --git a/Source/JavaScriptCore/jit/JSInterfaceJIT.h b/Source/JavaScriptCore/jit/JSInterfaceJIT.h
index 5d3f239..e1d9353 100644
--- a/Source/JavaScriptCore/jit/JSInterfaceJIT.h
+++ b/Source/JavaScriptCore/jit/JSInterfaceJIT.h
@@ -28,7 +28,6 @@
#include "JITCode.h"
#include "JITStubs.h"
-#include "JSImmediate.h"
#include "JSValue.h"
#include "MacroAssembler.h"
#include "RegisterFile.h"
@@ -154,21 +153,51 @@ namespace JSC {
static const FPRegisterID fpRegT1 = MIPSRegisters::f6;
static const FPRegisterID fpRegT2 = MIPSRegisters::f8;
static const FPRegisterID fpRegT3 = MIPSRegisters::f10;
+#elif CPU(SH4)
+ static const RegisterID timeoutCheckRegister = SH4Registers::r8;
+ static const RegisterID callFrameRegister = SH4Registers::fp;
+
+ static const RegisterID regT0 = SH4Registers::r0;
+ static const RegisterID regT1 = SH4Registers::r1;
+ static const RegisterID regT2 = SH4Registers::r2;
+ static const RegisterID regT3 = SH4Registers::r10;
+ static const RegisterID regT4 = SH4Registers::r4;
+ static const RegisterID regT5 = SH4Registers::r5;
+ static const RegisterID regT6 = SH4Registers::r6;
+ static const RegisterID regT7 = SH4Registers::r7;
+ static const RegisterID firstArgumentRegister =regT4;
+
+ static const RegisterID returnValueRegister = SH4Registers::r0;
+ static const RegisterID cachedResultRegister = SH4Registers::r0;
+
+ static const FPRegisterID fpRegT0 = SH4Registers::fr0;
+ static const FPRegisterID fpRegT1 = SH4Registers::fr2;
+ static const FPRegisterID fpRegT2 = SH4Registers::fr4;
+ static const FPRegisterID fpRegT3 = SH4Registers::fr6;
+ static const FPRegisterID fpRegT4 = SH4Registers::fr8;
+ static const FPRegisterID fpRegT5 = SH4Registers::fr10;
+ static const FPRegisterID fpRegT6 = SH4Registers::fr12;
+ static const FPRegisterID fpRegT7 = SH4Registers::fr14;
#else
#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;
+ static const unsigned Int32Tag = 0xffffffff;
COMPILE_ASSERT(Int32Tag == JSValue::Int32Tag, Int32Tag_out_of_sync);
#else
- static const unsigned Int32Tag = JSImmediate::TagTypeNumber >> 32;
+ static const unsigned Int32Tag = 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);
+ inline void storePtrWithWriteBarrier(TrustedImmPtr ptr, RegisterID /* owner */, Address dest)
+ {
+ storePtr(ptr, dest);
+ }
+
#if USE(JSVALUE32_64)
inline Jump emitJumpIfNotJSCell(unsigned virtualRegisterIndex);
inline Address tagFor(int index, RegisterID base = callFrameRegister);