summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/jit
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2010-09-30 15:42:16 +0100
committerSteve Block <steveblock@google.com>2010-10-07 10:59:29 +0100
commitbec39347bb3bb5bf1187ccaf471d26247f28b585 (patch)
tree56bdc4c2978fbfd3d79d0d36d5d6c640ecc09cc8 /JavaScriptCore/jit
parent90b7966e7815b262cd19ac25f03aaad9b21fdc06 (diff)
downloadexternal_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.zip
external_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.tar.gz
external_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.tar.bz2
Merge WebKit at r68651 : Initial merge by git.
Change-Id: I3d6bff59f17eedd6722723354f386fec9be8ad12
Diffstat (limited to 'JavaScriptCore/jit')
-rw-r--r--JavaScriptCore/jit/JIT.cpp7
-rw-r--r--JavaScriptCore/jit/JIT.h7
-rw-r--r--JavaScriptCore/jit/JITCall32_64.cpp12
-rw-r--r--JavaScriptCore/jit/JITOpcodes.cpp192
-rw-r--r--JavaScriptCore/jit/JITOpcodes32_64.cpp100
-rw-r--r--JavaScriptCore/jit/JITStubs.cpp35
-rw-r--r--JavaScriptCore/jit/JITStubs.h7
7 files changed, 294 insertions, 66 deletions
diff --git a/JavaScriptCore/jit/JIT.cpp b/JavaScriptCore/jit/JIT.cpp
index 4466fbd..a508d0c 100644
--- a/JavaScriptCore/jit/JIT.cpp
+++ b/JavaScriptCore/jit/JIT.cpp
@@ -225,7 +225,7 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_get_callee)
DEFINE_OP(op_create_this)
DEFINE_OP(op_convert_this)
- DEFINE_OP(op_init_arguments)
+ DEFINE_OP(op_init_lazy_reg)
DEFINE_OP(op_create_arguments)
DEFINE_OP(op_debug)
DEFINE_OP(op_del_by_id)
@@ -238,7 +238,9 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_eq)
DEFINE_OP(op_eq_null)
DEFINE_OP(op_get_by_id)
+ DEFINE_OP(op_get_arguments_length)
DEFINE_OP(op_get_by_val)
+ DEFINE_OP(op_get_argument_by_val)
DEFINE_OP(op_get_by_pname)
DEFINE_OP(op_get_global_var)
DEFINE_OP(op_get_pnames)
@@ -399,7 +401,9 @@ void JIT::privateCompileSlowCases()
#endif
DEFINE_SLOWCASE_OP(op_eq)
DEFINE_SLOWCASE_OP(op_get_by_id)
+ DEFINE_SLOWCASE_OP(op_get_arguments_length)
DEFINE_SLOWCASE_OP(op_get_by_val)
+ DEFINE_SLOWCASE_OP(op_get_argument_by_val)
DEFINE_SLOWCASE_OP(op_get_by_pname)
DEFINE_SLOWCASE_OP(op_instanceof)
DEFINE_SLOWCASE_OP(op_jfalse)
@@ -408,6 +412,7 @@ void JIT::privateCompileSlowCases()
DEFINE_SLOWCASE_OP(op_jlesseq)
DEFINE_SLOWCASE_OP(op_jnlesseq)
DEFINE_SLOWCASE_OP(op_jtrue)
+ DEFINE_SLOWCASE_OP(op_load_varargs)
DEFINE_SLOWCASE_OP(op_loop_if_less)
DEFINE_SLOWCASE_OP(op_loop_if_lesseq)
DEFINE_SLOWCASE_OP(op_loop_if_true)
diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h
index 6f1168b..6b2e70e 100644
--- a/JavaScriptCore/jit/JIT.h
+++ b/JavaScriptCore/jit/JIT.h
@@ -748,11 +748,13 @@ namespace JSC {
void emit_op_eq(Instruction*);
void emit_op_eq_null(Instruction*);
void emit_op_get_by_id(Instruction*);
+ void emit_op_get_arguments_length(Instruction*);
void emit_op_get_by_val(Instruction*);
+ void emit_op_get_argument_by_val(Instruction*);
void emit_op_get_by_pname(Instruction*);
void emit_op_get_global_var(Instruction*);
void emit_op_get_scoped_var(Instruction*);
- void emit_op_init_arguments(Instruction*);
+ void emit_op_init_lazy_reg(Instruction*);
void emit_op_instanceof(Instruction*);
void emit_op_jeq_null(Instruction*);
void emit_op_jfalse(Instruction*);
@@ -846,7 +848,9 @@ namespace JSC {
void emitSlow_op_div(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_get_arguments_length(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_get_argument_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_get_by_pname(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -855,6 +859,7 @@ namespace JSC {
void emitSlow_op_jlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&, bool invert = false);
void emitSlow_op_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_load_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_loop_if_less(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_loop_if_lesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_loop_if_true(Instruction*, Vector<SlowCaseEntry>::iterator&);
diff --git a/JavaScriptCore/jit/JITCall32_64.cpp b/JavaScriptCore/jit/JITCall32_64.cpp
index aa8e987..e4005ae 100644
--- a/JavaScriptCore/jit/JITCall32_64.cpp
+++ b/JavaScriptCore/jit/JITCall32_64.cpp
@@ -180,18 +180,6 @@ void JIT::emit_op_call_eval(Instruction* currentInstruction)
compileOpCall(op_call_eval, currentInstruction, m_callLinkInfoIndex++);
}
-void JIT::emit_op_load_varargs(Instruction* currentInstruction)
-{
- int argCountDst = currentInstruction[1].u.operand;
- int argsOffset = currentInstruction[2].u.operand;
-
- 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)));
-}
-
void JIT::emit_op_call_varargs(Instruction* currentInstruction)
{
compileOpCallVarargs(currentInstruction);
diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp
index 2bfba83..c81932a 100644
--- a/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/JavaScriptCore/jit/JITOpcodes.cpp
@@ -28,6 +28,7 @@
#if ENABLE(JIT)
#include "JIT.h"
+#include "Arguments.h"
#include "JITInlineMethods.h"
#include "JITStubCall.h"
#include "JSArray.h"
@@ -396,6 +397,10 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
emitJumpSlowCaseIfNotJSCell(regT0, baseVal);
emitJumpSlowCaseIfNotJSCell(regT1, proto);
+ // Check that prototype is an object
+ loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT3);
+ addSlowCase(branch8(NotEqual, Address(regT3, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+
// Check that baseVal 'ImplementsDefaultHasInstance'.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
addSlowCase(branchTest8(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
@@ -421,13 +426,6 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
emitPutVirtualRegister(dst);
}
-void JIT::emit_op_new_func(Instruction* currentInstruction)
-{
- JITStubCall stubCall(this, cti_op_new_func);
- stubCall.addArgument(ImmPtr(m_codeBlock->functionDecl(currentInstruction[2].u.operand)));
- stubCall.call(currentInstruction[1].u.operand);
-}
-
void JIT::emit_op_call(Instruction* currentInstruction)
{
compileOpCall(op_call, currentInstruction, m_callLinkInfoIndex++);
@@ -438,18 +436,6 @@ void JIT::emit_op_call_eval(Instruction* currentInstruction)
compileOpCall(op_call_eval, currentInstruction, m_callLinkInfoIndex++);
}
-void JIT::emit_op_load_varargs(Instruction* currentInstruction)
-{
- int argCountDst = currentInstruction[1].u.operand;
- int argsOffset = currentInstruction[2].u.operand;
-
- 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)));
-}
-
void JIT::emit_op_call_varargs(Instruction* currentInstruction)
{
compileOpCallVarargs(currentInstruction);
@@ -1225,12 +1211,11 @@ void JIT::emit_op_create_arguments(Instruction* currentInstruction)
argsCreated.link(this);
}
-void JIT::emit_op_init_arguments(Instruction* currentInstruction)
+void JIT::emit_op_init_lazy_reg(Instruction* currentInstruction)
{
unsigned dst = currentInstruction[1].u.operand;
storePtr(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * dst));
- storePtr(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * (unmodifiedArgumentsRegister(dst))));
}
void JIT::emit_op_convert_this(Instruction* currentInstruction)
@@ -1447,6 +1432,7 @@ void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCas
linkSlowCaseIfNotJSCell(iter, baseVal);
linkSlowCaseIfNotJSCell(iter, proto);
linkSlowCase(iter);
+ linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_instanceof);
stubCall.addArgument(value, regT2);
stubCall.addArgument(baseVal, regT2);
@@ -1484,6 +1470,88 @@ void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCa
stubCall.call(currentInstruction[1].u.operand);
}
+void JIT::emit_op_get_arguments_length(Instruction* currentInstruction)
+{
+ int dst = currentInstruction[1].u.operand;
+ int argumentsRegister = currentInstruction[2].u.operand;
+ addSlowCase(branchTestPtr(NonZero, addressFor(argumentsRegister)));
+ emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
+ sub32(Imm32(1), regT0);
+ emitFastArithReTagImmediate(regT0, regT0);
+ emitPutVirtualRegister(dst, regT0);
+}
+
+void JIT::emitSlow_op_get_arguments_length(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkSlowCase(iter);
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned base = currentInstruction[2].u.operand;
+ Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
+
+ emitGetVirtualRegister(base, regT0);
+ JITStubCall stubCall(this, cti_op_get_by_id_generic);
+ stubCall.addArgument(regT0);
+ stubCall.addArgument(ImmPtr(ident));
+ stubCall.call(dst);
+}
+
+void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction)
+{
+ int dst = currentInstruction[1].u.operand;
+ int argumentsRegister = currentInstruction[2].u.operand;
+ int property = currentInstruction[3].u.operand;
+ addSlowCase(branchTestPtr(NonZero, addressFor(argumentsRegister)));
+ emitGetVirtualRegister(property, regT1);
+ addSlowCase(emitJumpIfNotImmediateInteger(regT1));
+ add32(Imm32(1), regT1);
+ // regT1 now contains the integer index of the argument we want, including this
+ emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT2);
+ addSlowCase(branch32(AboveOrEqual, regT1, regT2));
+
+ Jump skipOutofLineParams;
+ int numArgs = m_codeBlock->m_numParameters;
+ if (numArgs) {
+ Jump notInInPlaceArgs = branch32(AboveOrEqual, regT1, Imm32(numArgs));
+ addPtr(Imm32(static_cast<unsigned>(-(RegisterFile::CallFrameHeaderSize + numArgs) * sizeof(Register))), callFrameRegister, regT0);
+ loadPtr(BaseIndex(regT0, regT1, TimesEight, 0), regT0);
+ skipOutofLineParams = jump();
+ notInInPlaceArgs.link(this);
+ }
+
+ addPtr(Imm32(static_cast<unsigned>(-(RegisterFile::CallFrameHeaderSize + numArgs) * sizeof(Register))), callFrameRegister, regT0);
+ mul32(Imm32(sizeof(Register)), regT2, regT2);
+ subPtr(regT2, regT0);
+ loadPtr(BaseIndex(regT0, regT1, TimesEight, 0), regT0);
+ if (numArgs)
+ skipOutofLineParams.link(this);
+ emitPutVirtualRegister(dst, regT0);
+}
+
+void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned arguments = currentInstruction[2].u.operand;
+ unsigned property = currentInstruction[3].u.operand;
+
+ linkSlowCase(iter);
+ Jump skipArgumentsCreation = jump();
+
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ if (m_codeBlock->m_numParameters == 1)
+ JITStubCall(this, cti_op_create_arguments_no_params).call();
+ else
+ JITStubCall(this, cti_op_create_arguments).call();
+ emitPutVirtualRegister(arguments);
+ emitPutVirtualRegister(unmodifiedArgumentsRegister(arguments));
+
+ skipArgumentsCreation.link(this);
+ JITStubCall stubCall(this, cti_op_get_by_val);
+ stubCall.addArgument(arguments, regT2);
+ stubCall.addArgument(property, regT2);
+ stubCall.call(dst);
+}
+
#endif // !USE(JSVALUE32_64)
void JIT::emit_op_resolve_global_dynamic(Instruction* currentInstruction)
@@ -1528,6 +1596,88 @@ void JIT::emit_op_new_regexp(Instruction* currentInstruction)
stubCall.call(currentInstruction[1].u.operand);
}
+void JIT::emit_op_load_varargs(Instruction* currentInstruction)
+{
+ int argCountDst = currentInstruction[1].u.operand;
+ int argsOffset = currentInstruction[2].u.operand;
+ int expectedParams = m_codeBlock->m_numParameters - 1;
+ // Don't do inline copying if we aren't guaranteed to have a single stream
+ // of arguments
+ if (expectedParams) {
+ 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)));
+ return;
+ }
+
+#if USE(JSVALUE32_64)
+ addSlowCase(branch32(NotEqual, tagFor(argsOffset), Imm32(JSValue::EmptyValueTag)));
+#else
+ addSlowCase(branchTestPtr(NonZero, addressFor(argsOffset)));
+#endif
+ // Load arg count into regT0
+ emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
+ storePtr(regT0, addressFor(argCountDst));
+ Jump endBranch = branch32(Equal, regT0, Imm32(1));
+
+ mul32(Imm32(sizeof(Register)), regT0, regT3);
+ addPtr(Imm32(static_cast<unsigned>(sizeof(Register) - RegisterFile::CallFrameHeaderSize * sizeof(Register))), callFrameRegister, regT1);
+ subPtr(regT3, regT1); // regT1 is now the start of the out of line arguments
+ addPtr(Imm32(argsOffset * sizeof(Register)), callFrameRegister, regT2); // regT2 is the target buffer
+
+ // Bounds check the registerfile
+ addPtr(regT2, regT3);
+ addSlowCase(branchPtr(Below, AbsoluteAddress(&m_globalData->interpreter->registerFile().m_end), regT3));
+
+ sub32(Imm32(1), regT0);
+ Label loopStart = label();
+ loadPtr(BaseIndex(regT1, regT0, TimesEight, static_cast<unsigned>(0 - 2 * sizeof(Register))), regT3);
+ storePtr(regT3, BaseIndex(regT2, regT0, TimesEight, static_cast<unsigned>(0 - sizeof(Register))));
+#if USE(JSVALUE32_64)
+ loadPtr(BaseIndex(regT1, regT0, TimesEight, static_cast<unsigned>(sizeof(void*) - 2 * sizeof(Register))), regT3);
+ storePtr(regT3, BaseIndex(regT2, regT0, TimesEight, static_cast<unsigned>(sizeof(void*) - sizeof(Register))));
+#endif
+ branchSubPtr(NonZero, Imm32(1), regT0).linkTo(loopStart, this);
+ endBranch.link(this);
+}
+
+void JIT::emitSlow_op_load_varargs(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ int argCountDst = currentInstruction[1].u.operand;
+ int argsOffset = currentInstruction[2].u.operand;
+ int expectedParams = m_codeBlock->m_numParameters - 1;
+ if (expectedParams)
+ return;
+
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ 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)));
+}
+
+void JIT::emit_op_new_func(Instruction* currentInstruction)
+{
+ Jump lazyJump;
+ int dst = currentInstruction[1].u.operand;
+ if (currentInstruction[3].u.operand) {
+#if USE(JSVALUE32_64)
+ lazyJump = branch32(NotEqual, tagFor(dst), Imm32(JSValue::EmptyValueTag));
+#else
+ lazyJump = branchTestPtr(NonZero, addressFor(dst));
+#endif
+ }
+ JITStubCall stubCall(this, cti_op_new_func);
+ stubCall.addArgument(ImmPtr(m_codeBlock->functionDecl(currentInstruction[2].u.operand)));
+ stubCall.call(currentInstruction[1].u.operand);
+ if (currentInstruction[3].u.operand)
+ lazyJump.link(this);
+}
+
// For both JSValue32_64 and JSValue32
#if ENABLE(JIT_USE_SOFT_MODULO)
#if CPU(ARM_TRADITIONAL)
diff --git a/JavaScriptCore/jit/JITOpcodes32_64.cpp b/JavaScriptCore/jit/JITOpcodes32_64.cpp
index 1ad19b7..ad3b558 100644
--- a/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -525,7 +525,11 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
emitJumpSlowCaseIfNotJSCell(value);
emitJumpSlowCaseIfNotJSCell(baseVal);
emitJumpSlowCaseIfNotJSCell(proto);
-
+
+ // Check that prototype is an object
+ loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT3);
+ addSlowCase(branch8(NotEqual, Address(regT3, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+
// Check that baseVal 'ImplementsDefaultHasInstance'.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
addSlowCase(branchTest8(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
@@ -562,6 +566,7 @@ void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCas
linkSlowCaseIfNotJSCell(iter, baseVal);
linkSlowCaseIfNotJSCell(iter, proto);
linkSlowCase(iter);
+ linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_instanceof);
stubCall.addArgument(value);
@@ -570,13 +575,6 @@ void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCas
stubCall.call(dst);
}
-void JIT::emit_op_new_func(Instruction* currentInstruction)
-{
- JITStubCall stubCall(this, cti_op_new_func);
- stubCall.addArgument(ImmPtr(m_codeBlock->functionDecl(currentInstruction[2].u.operand)));
- stubCall.call(currentInstruction[1].u.operand);
-}
-
void JIT::emit_op_get_global_var(Instruction* currentInstruction)
{
int dst = currentInstruction[1].u.operand;
@@ -1493,12 +1491,11 @@ void JIT::emit_op_create_arguments(Instruction* currentInstruction)
argsCreated.link(this);
}
-void JIT::emit_op_init_arguments(Instruction* currentInstruction)
+void JIT::emit_op_init_lazy_reg(Instruction* currentInstruction)
{
unsigned dst = currentInstruction[1].u.operand;
emitStore(dst, JSValue());
- emitStore(unmodifiedArgumentsRegister(dst), JSValue());
}
void JIT::emit_op_get_callee(Instruction* currentInstruction)
@@ -1565,6 +1562,89 @@ void JIT::emit_op_profile_did_call(Instruction* currentInstruction)
noProfiler.link(this);
}
+void JIT::emit_op_get_arguments_length(Instruction* currentInstruction)
+{
+ int dst = currentInstruction[1].u.operand;
+ int argumentsRegister = currentInstruction[2].u.operand;
+ addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), Imm32(JSValue::EmptyValueTag)));
+ emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
+ sub32(Imm32(1), regT0);
+ emitStoreInt32(dst, regT0);
+}
+
+void JIT::emitSlow_op_get_arguments_length(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkSlowCase(iter);
+ int dst = currentInstruction[1].u.operand;
+ int base = currentInstruction[2].u.operand;
+ int ident = currentInstruction[3].u.operand;
+
+ JITStubCall stubCall(this, cti_op_get_by_id_generic);
+ stubCall.addArgument(base);
+ stubCall.addArgument(ImmPtr(&(m_codeBlock->identifier(ident))));
+ stubCall.call(dst);
+}
+
+void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction)
+{
+ int dst = currentInstruction[1].u.operand;
+ int argumentsRegister = currentInstruction[2].u.operand;
+ int property = currentInstruction[3].u.operand;
+ addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), Imm32(JSValue::EmptyValueTag)));
+ emitLoad(property, regT1, regT2);
+ addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ add32(Imm32(1), regT2);
+ // regT2 now contains the integer index of the argument we want, including this
+ emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT3);
+ addSlowCase(branch32(AboveOrEqual, regT2, regT3));
+
+ Jump skipOutofLineParams;
+ int numArgs = m_codeBlock->m_numParameters;
+ if (numArgs) {
+ Jump notInInPlaceArgs = branch32(AboveOrEqual, regT2, Imm32(numArgs));
+ addPtr(Imm32(static_cast<unsigned>(-(RegisterFile::CallFrameHeaderSize + numArgs) * sizeof(Register))), callFrameRegister, regT1);
+ loadPtr(BaseIndex(regT1, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
+ loadPtr(BaseIndex(regT1, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
+ skipOutofLineParams = jump();
+ notInInPlaceArgs.link(this);
+ }
+
+ addPtr(Imm32(static_cast<unsigned>(-(RegisterFile::CallFrameHeaderSize + numArgs) * sizeof(Register))), callFrameRegister, regT1);
+ mul32(Imm32(sizeof(Register)), regT3, regT3);
+ subPtr(regT3, regT1);
+ loadPtr(BaseIndex(regT1, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
+ loadPtr(BaseIndex(regT1, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
+ if (numArgs)
+ skipOutofLineParams.link(this);
+ emitStore(dst, regT1, regT0);
+}
+
+void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned arguments = currentInstruction[2].u.operand;
+ unsigned property = currentInstruction[3].u.operand;
+
+ linkSlowCase(iter);
+ Jump skipArgumentsCreation = jump();
+
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ if (m_codeBlock->m_numParameters == 1)
+ JITStubCall(this, cti_op_create_arguments_no_params).call();
+ else
+ JITStubCall(this, cti_op_create_arguments).call();
+
+ emitStore(arguments, regT1, regT0);
+ emitStore(unmodifiedArgumentsRegister(arguments), regT1, regT0);
+
+ skipArgumentsCreation.link(this);
+ JITStubCall stubCall(this, cti_op_get_by_val);
+ stubCall.addArgument(arguments);
+ stubCall.addArgument(property);
+ stubCall.call(dst);
+}
+
} // namespace JSC
#endif // USE(JSVALUE32_64)
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index d5e55b4..f1ec079 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -234,15 +235,15 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
#elif COMPILER(GCC) && CPU(ARM_THUMB2)
-#define THUNK_RETURN_ADDRESS_OFFSET 0x40
-#define PRESERVED_RETURN_ADDRESS_OFFSET 0x44
-#define PRESERVED_R4_OFFSET 0x48
-#define PRESERVED_R5_OFFSET 0x4C
-#define PRESERVED_R6_OFFSET 0x50
-#define REGISTER_FILE_OFFSET 0x54
-#define CALLFRAME_OFFSET 0x58
-#define EXCEPTION_OFFSET 0x5C
-#define ENABLE_PROFILER_REFERENCE_OFFSET 0x64
+#define THUNK_RETURN_ADDRESS_OFFSET 0x38
+#define PRESERVED_RETURN_ADDRESS_OFFSET 0x3C
+#define PRESERVED_R4_OFFSET 0x40
+#define PRESERVED_R5_OFFSET 0x44
+#define PRESERVED_R6_OFFSET 0x48
+#define REGISTER_FILE_OFFSET 0x4C
+#define CALLFRAME_OFFSET 0x50
+#define EXCEPTION_OFFSET 0x54
+#define ENABLE_PROFILER_REFERENCE_OFFSET 0x58
#elif (COMPILER(GCC) || COMPILER(RVCT)) && CPU(ARM_TRADITIONAL)
@@ -467,14 +468,14 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
#elif COMPILER(GCC) && CPU(ARM_THUMB2)
-#define THUNK_RETURN_ADDRESS_OFFSET 0x1C
-#define PRESERVED_RETURN_ADDRESS_OFFSET 0x20
-#define PRESERVED_R4_OFFSET 0x24
-#define PRESERVED_R5_OFFSET 0x28
-#define PRESERVED_R6_OFFSET 0x2C
-#define REGISTER_FILE_OFFSET 0x30
-#define CALLFRAME_OFFSET 0x34
-#define EXCEPTION_OFFSET 0x38
+#define THUNK_RETURN_ADDRESS_OFFSET 0x20
+#define PRESERVED_RETURN_ADDRESS_OFFSET 0x24
+#define PRESERVED_R4_OFFSET 0x28
+#define PRESERVED_R5_OFFSET 0x2C
+#define PRESERVED_R6_OFFSET 0x30
+#define REGISTER_FILE_OFFSET 0x34
+#define CALLFRAME_OFFSET 0x38
+#define EXCEPTION_OFFSET 0x3C
#define ENABLE_PROFILER_REFERENCE_OFFSET 0x40
#elif (COMPILER(GCC) || COMPILER(RVCT)) && CPU(ARM_TRADITIONAL)
diff --git a/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h
index d3d7c53..2b22e6d 100644
--- a/JavaScriptCore/jit/JITStubs.h
+++ b/JavaScriptCore/jit/JITStubs.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -146,8 +147,8 @@ namespace JSC {
struct JITStackFrame {
JITStubArg reserved; // Unused
JITStubArg args[6];
-#if USE(JSVALUE32_64)
- void* padding[2]; // Maintain 16-byte stack alignment.
+#if !USE(JSVALUE32_64)
+ void* padding; // Maintain 16-byte stack alignment.
#endif
ReturnAddressPtr thunkReturnAddress;
@@ -162,8 +163,6 @@ namespace JSC {
CallFrame* callFrame;
JSValue* exception;
- void* padding2;
-
// These arguments passed on the stack.
Profiler** enabledProfilerReference;
JSGlobalData* globalData;