37 #ifndef V8_IA32_ASSEMBLER_IA32_INL_H_
38 #define V8_IA32_ASSEMBLER_IA32_INL_H_
50 void RelocInfo::apply(intptr_t delta) {
55 }
else if (rmode_ == JS_RETURN && IsPatchedReturnSequence()) {
61 }
else if (rmode_ == DEBUG_BREAK_SLOT && IsPatchedDebugBreakSlotSequence()) {
67 }
else if (IsInternalReference(rmode_)) {
76 Address RelocInfo::target_address() {
82 Address RelocInfo::target_address_address() {
84 || rmode_ == EMBEDDED_OBJECT
85 || rmode_ == EXTERNAL_REFERENCE);
86 return reinterpret_cast<Address>(pc_);
90 int RelocInfo::target_address_size() {
100 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
106 Object* RelocInfo::target_object() {
107 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
112 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) {
113 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
118 Object** RelocInfo::target_object_address() {
119 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
125 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
130 target->IsHeapObject()) {
131 host()->GetHeap()->incremental_marking()->RecordWrite(
137 Address* RelocInfo::target_reference_address() {
138 ASSERT(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
139 return reinterpret_cast<Address*
>(pc_);
143 Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
144 ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
146 return Handle<JSGlobalPropertyCell>(
147 reinterpret_cast<JSGlobalPropertyCell**
>(address));
151 JSGlobalPropertyCell* RelocInfo::target_cell() {
152 ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
157 void RelocInfo::set_target_cell(JSGlobalPropertyCell* cell,
159 ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
166 host()->GetHeap()->incremental_marking()->RecordWrite(
172 Address RelocInfo::call_address() {
173 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
174 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
179 void RelocInfo::set_call_address(
Address target) {
180 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
181 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
183 if (host() !=
NULL) {
185 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
191 Object* RelocInfo::call_object() {
192 return *call_object_address();
196 void RelocInfo::set_call_object(
Object* target) {
197 *call_object_address() = target;
201 Object** RelocInfo::call_object_address() {
202 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
203 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
204 return reinterpret_cast<Object**
>(pc_ + 1);
208 bool RelocInfo::IsPatchedReturnSequence() {
213 bool RelocInfo::IsPatchedDebugBreakSlotSequence() {
218 void RelocInfo::Visit(ObjectVisitor* visitor) {
219 RelocInfo::Mode mode = rmode();
220 if (mode == RelocInfo::EMBEDDED_OBJECT) {
221 visitor->VisitEmbeddedPointer(
this);
223 }
else if (RelocInfo::IsCodeTarget(mode)) {
224 visitor->VisitCodeTarget(
this);
225 }
else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
226 visitor->VisitGlobalPropertyCell(
this);
227 }
else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
228 visitor->VisitExternalReference(
this);
230 #ifdef ENABLE_DEBUGGER_SUPPORT
232 }
else if (((RelocInfo::IsJSReturn(mode) &&
233 IsPatchedReturnSequence()) ||
234 (RelocInfo::IsDebugBreakSlot(mode) &&
235 IsPatchedDebugBreakSlotSequence())) &&
236 Isolate::Current()->debug()->has_break_points()) {
237 visitor->VisitDebugTarget(
this);
240 visitor->VisitRuntimeEntry(
this);
245 template<
typename StaticVisitor>
246 void RelocInfo::Visit(Heap* heap) {
247 RelocInfo::Mode mode = rmode();
248 if (mode == RelocInfo::EMBEDDED_OBJECT) {
249 StaticVisitor::VisitEmbeddedPointer(heap,
this);
251 }
else if (RelocInfo::IsCodeTarget(mode)) {
252 StaticVisitor::VisitCodeTarget(heap,
this);
253 }
else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
254 StaticVisitor::VisitGlobalPropertyCell(heap,
this);
255 }
else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
256 StaticVisitor::VisitExternalReference(
this);
258 #ifdef ENABLE_DEBUGGER_SUPPORT
259 }
else if (heap->isolate()->debug()->has_break_points() &&
260 ((RelocInfo::IsJSReturn(mode) &&
261 IsPatchedReturnSequence()) ||
262 (RelocInfo::IsDebugBreakSlot(mode) &&
263 IsPatchedDebugBreakSlotSequence()))) {
264 StaticVisitor::VisitDebugTarget(heap,
this);
267 StaticVisitor::VisitRuntimeEntry(
this);
273 Immediate::Immediate(
int x) {
279 Immediate::Immediate(
const ExternalReference& ext) {
280 x_ =
reinterpret_cast<int32_t>(ext.address());
281 rmode_ = RelocInfo::EXTERNAL_REFERENCE;
285 Immediate::Immediate(Label* internal_offset) {
286 x_ =
reinterpret_cast<int32_t>(internal_offset);
287 rmode_ = RelocInfo::INTERNAL_REFERENCE;
291 Immediate::Immediate(Handle<Object> handle) {
295 if (obj->IsHeapObject()) {
296 x_ =
reinterpret_cast<intptr_t
>(handle.location());
297 rmode_ = RelocInfo::EMBEDDED_OBJECT;
300 x_ =
reinterpret_cast<intptr_t
>(obj);
306 Immediate::Immediate(Smi* value) {
307 x_ =
reinterpret_cast<intptr_t
>(value);
312 Immediate::Immediate(
Address addr) {
313 x_ =
reinterpret_cast<int32_t>(addr);
318 void Assembler::emit(uint32_t x) {
319 *
reinterpret_cast<uint32_t*
>(pc_) = x;
320 pc_ +=
sizeof(uint32_t);
324 void Assembler::emit(Handle<Object> handle) {
328 if (obj->IsHeapObject()) {
329 emit(reinterpret_cast<intptr_t>(handle.location()),
330 RelocInfo::EMBEDDED_OBJECT);
333 emit(reinterpret_cast<intptr_t>(obj));
338 void Assembler::emit(uint32_t x, RelocInfo::Mode rmode, TypeFeedbackId
id) {
339 if (rmode == RelocInfo::CODE_TARGET && !
id.IsNone()) {
340 RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID,
id.ToInt());
342 RecordRelocInfo(rmode);
348 void Assembler::emit(
const Immediate& x) {
349 if (x.rmode_ == RelocInfo::INTERNAL_REFERENCE) {
350 Label* label =
reinterpret_cast<Label*
>(x.x_);
351 emit_code_relative_offset(label);
359 void Assembler::emit_code_relative_offset(Label* label) {
360 if (label->is_bound()) {
365 emit_disp(label, Displacement::CODE_RELATIVE);
370 void Assembler::emit_w(
const Immediate& x) {
373 reinterpret_cast<uint16_t*
>(pc_)[0] = value;
379 return pc +
sizeof(
int32_t) + *reinterpret_cast<int32_t*>(pc);
385 *p = target - (pc +
sizeof(
int32_t));
395 Displacement Assembler::disp_at(Label*
L) {
396 return Displacement(long_at(L->pos()));
400 void Assembler::disp_at_put(Label* L, Displacement disp) {
401 long_at_put(L->pos(), disp.data());
405 void Assembler::emit_disp(Label* L, Displacement::Type type) {
406 Displacement disp(L, type);
408 emit(static_cast<int>(disp.data()));
412 void Assembler::emit_near_disp(Label* L) {
414 if (L->is_near_linked()) {
415 int offset = L->near_link_pos() -
pc_offset();
417 disp =
static_cast<byte>(offset & 0xFF);
424 void Operand::set_modrm(
int mod, Register rm) {
426 buf_[0] = mod << 6 | rm.code();
431 void Operand::set_sib(
ScaleFactor scale, Register index, Register base) {
433 ASSERT((scale & -4) == 0);
436 buf_[1] = scale << 6 | index.code() << 3 | base.code();
441 void Operand::set_disp8(int8_t disp) {
442 ASSERT(len_ == 1 || len_ == 2);
443 *
reinterpret_cast<int8_t*
>(&buf_[len_++]) = disp;
447 void Operand::set_dispr(
int32_t disp, RelocInfo::Mode rmode) {
448 ASSERT(len_ == 1 || len_ == 2);
455 Operand::Operand(Register reg) {
461 Operand::Operand(XMMRegister xmm_reg) {
462 Register reg = { xmm_reg.code() };
467 Operand::Operand(
int32_t disp, RelocInfo::Mode rmode) {
470 set_dispr(disp, rmode);
475 #endif // V8_IA32_ASSEMBLER_IA32_INL_H_
Isolate * isolate() const
static Object *& Object_at(Address addr)
static Handle< Object > & Object_Handle_at(Address addr)
static HeapObject * cast(Object *obj)
#define ASSERT(condition)
static const int kSpecialTargetSize
static Address & Address_at(Address addr)
static void set_target_address_at(Address pc, Address target)
static Code * GetCodeFromTargetAddress(Address address)
static const int kCallTargetAddressOffset
static bool IsNop(Instr instr, int type=NON_MARKING_NOP)
static Address target_address_at(Address pc)
static JSGlobalPropertyCell * FromValueAddress(Address value)
static Address target_address_from_return_address(Address pc)
static const int kHeaderSize
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
#define RUNTIME_ENTRY(name, nargs, ressize)
static void FlushICache(void *start, size_t size)
static const int kValueOffset