54
54
// TODO: we want to reuse values that are already in registers if we can - add a register allocator!
55
55
if (m_codeBlock->isConstantRegisterIndex(src)) {
56
JSValuePtr value = m_codeBlock->getConstant(src);
57
move(ImmPtr(JSValuePtr::encode(value)), dst);
56
JSValue value = m_codeBlock->getConstant(src);
57
move(ImmPtr(JSValue::encode(value)), dst);
58
58
killLastResultRegister();
112
112
peek(dst, argumentNumber);
115
ALWAYS_INLINE JSValuePtr JIT::getConstantOperand(unsigned src)
115
ALWAYS_INLINE JSValue JIT::getConstantOperand(unsigned src)
117
117
ASSERT(m_codeBlock->isConstantRegisterIndex(src));
118
118
return m_codeBlock->getConstant(src);
132
132
ALWAYS_INLINE void JIT::emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch)
134
134
if (m_codeBlock->isConstantRegisterIndex(src)) {
135
JSValuePtr value = m_codeBlock->getConstant(src);
136
emitPutJITStubArgConstant(JSValuePtr::encode(value), argumentNumber);
135
JSValue value = m_codeBlock->getConstant(src);
136
emitPutJITStubArgConstant(JSValue::encode(value), argumentNumber);
138
138
loadPtr(Address(callFrameRegister, src * sizeof(Register)), scratch);
139
139
emitPutJITStubArg(scratch, argumentNumber);
142
142
killLastResultRegister();
145
ALWAYS_INLINE void JIT::emitPutCTIParam(void* value, unsigned name)
147
poke(ImmPtr(value), name);
150
ALWAYS_INLINE void JIT::emitPutCTIParam(RegisterID from, unsigned name)
155
ALWAYS_INLINE void JIT::emitGetCTIParam(unsigned name, RegisterID to)
158
killLastResultRegister();
161
145
ALWAYS_INLINE void JIT::emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry)
163
147
storePtr(from, Address(callFrameRegister, entry * sizeof(Register)));
168
152
storePtr(ImmPtr(value), Address(callFrameRegister, entry * sizeof(Register)));
171
ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader(RegisterFile::CallFrameHeaderEntry entry, RegisterID to)
173
loadPtr(Address(callFrameRegister, entry * sizeof(Register)), to);
155
ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
157
loadPtr(Address(from, entry * sizeof(Register)), to);
158
killLastResultRegister();
161
ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
163
load32(Address(from, entry * sizeof(Register)), to);
174
164
killLastResultRegister();
184
174
ALWAYS_INLINE void JIT::emitInitRegister(unsigned dst)
186
storePtr(ImmPtr(JSValuePtr::encode(jsUndefined())), Address(callFrameRegister, dst * sizeof(Register)));
176
storePtr(ImmPtr(JSValue::encode(jsUndefined())), Address(callFrameRegister, dst * sizeof(Register)));
187
177
// FIXME: #ifndef NDEBUG, Write the correct m_type to the register.
200
190
ALWAYS_INLINE void JIT::restoreArgumentReference()
202
192
move(stackPointerRegister, firstArgumentRegister);
203
emitPutCTIParam(callFrameRegister, STUB_ARGS_callFrame);
193
poke(callFrameRegister, offsetof(struct JITStackFrame, callFrame) / sizeof (void*));
205
195
ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline()
214
204
ALWAYS_INLINE void JIT::restoreArgumentReference()
216
206
poke(stackPointerRegister);
217
emitPutCTIParam(callFrameRegister, STUB_ARGS_callFrame);
207
poke(callFrameRegister, offsetof(struct JITStackFrame, callFrame) / sizeof (void*));
219
209
ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline() {}
220
210
#else // JIT_STUB_ARGUMENT_VA_LIST
221
211
ALWAYS_INLINE void JIT::restoreArgumentReference()
223
emitPutCTIParam(callFrameRegister, STUB_ARGS_callFrame);
213
poke(callFrameRegister, offsetof(struct JITStackFrame, callFrame) / sizeof (void*));
225
215
ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline() {}
228
ALWAYS_INLINE JIT::Call JIT::emitCTICall_internal(void* helper)
230
ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
232
#if ENABLE(OPCODE_SAMPLING)
233
sampleInstruction(m_codeBlock->instructions().begin() + m_bytecodeIndex, true);
235
restoreArgumentReference();
236
Call ctiCall = call();
237
m_calls.append(CallRecord(ctiCall, m_bytecodeIndex, helper));
238
#if ENABLE(OPCODE_SAMPLING)
239
sampleInstruction(m_codeBlock->instructions().begin() + m_bytecodeIndex, false);
241
killLastResultRegister();
246
218
ALWAYS_INLINE JIT::Jump JIT::checkStructure(RegisterID reg, Structure* structure)
248
220
return branchPtr(NotEqual, Address(reg, FIELD_OFFSET(JSCell, m_structure)), ImmPtr(structure));
414
386
jump.linkTo(m_labels[m_bytecodeIndex + relativeOffset], this);
389
#if ENABLE(SAMPLING_FLAGS)
390
ALWAYS_INLINE void JIT::setSamplingFlag(int32_t flag)
394
or32(Imm32(1u << (flag - 1)), AbsoluteAddress(&SamplingFlags::s_flags));
397
ALWAYS_INLINE void JIT::clearSamplingFlag(int32_t flag)
401
and32(Imm32(~(1u << (flag - 1))), AbsoluteAddress(&SamplingFlags::s_flags));
405
#if ENABLE(SAMPLING_COUNTERS)
406
ALWAYS_INLINE void JIT::emitCount(AbstractSamplingCounter& counter, uint32_t count)
408
#if PLATFORM(X86_64) // Or any other 64-bit plattform.
409
addPtr(Imm32(count), AbsoluteAddress(&counter.m_counter));
410
#elif PLATFORM(X86) // Or any other little-endian 32-bit plattform.
411
intptr_t hiWord = reinterpret_cast<intptr_t>(&counter.m_counter) + sizeof(int32_t);
412
add32(Imm32(count), AbsoluteAddress(&counter.m_counter));
413
addWithCarry32(Imm32(0), AbsoluteAddress(reinterpret_cast<void*>(hiWord)));
415
#error "SAMPLING_FLAGS not implemented on this platform."
420
#if ENABLE(OPCODE_SAMPLING)
422
ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostFunction)
424
move(ImmPtr(m_interpreter->sampler()->sampleSlot()), X86::ecx);
425
storePtr(ImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), X86::ecx);
428
ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostFunction)
430
storePtr(ImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), m_interpreter->sampler()->sampleSlot());
435
#if ENABLE(CODEBLOCK_SAMPLING)
437
ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock)
439
move(ImmPtr(m_interpreter->sampler()->codeBlockSlot()), X86::ecx);
440
storePtr(ImmPtr(codeBlock), X86::ecx);
443
ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock)
445
storePtr(ImmPtr(codeBlock), m_interpreter->sampler()->codeBlockSlot());
419
451
#endif // ENABLE(JIT)