OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 21 matching lines...) Expand all Loading... |
32 // modified significantly by Google Inc. | 32 // modified significantly by Google Inc. |
33 // Copyright 2012 the V8 project authors. All rights reserved. | 33 // Copyright 2012 the V8 project authors. All rights reserved. |
34 | 34 |
35 // A light-weight IA32 Assembler. | 35 // A light-weight IA32 Assembler. |
36 | 36 |
37 #ifndef V8_X87_ASSEMBLER_X87_INL_H_ | 37 #ifndef V8_X87_ASSEMBLER_X87_INL_H_ |
38 #define V8_X87_ASSEMBLER_X87_INL_H_ | 38 #define V8_X87_ASSEMBLER_X87_INL_H_ |
39 | 39 |
40 #include "src/x87/assembler-x87.h" | 40 #include "src/x87/assembler-x87.h" |
41 | 41 |
42 #include "src/cpu.h" | 42 #include "src/assembler.h" |
43 #include "src/debug.h" | 43 #include "src/debug.h" |
44 | 44 |
45 namespace v8 { | 45 namespace v8 { |
46 namespace internal { | 46 namespace internal { |
47 | 47 |
48 bool CpuFeatures::SupportsCrankshaft() { return false; } | 48 bool CpuFeatures::SupportsCrankshaft() { return false; } |
49 | 49 |
50 | 50 |
51 static const byte kCallOpcode = 0xE8; | 51 static const byte kCallOpcode = 0xE8; |
52 static const int kNoCodeAgeSequenceLength = 5; | 52 static const int kNoCodeAgeSequenceLength = 5; |
53 | 53 |
54 | 54 |
55 // The modes possibly affected by apply must be in kApplyMask. | 55 // The modes possibly affected by apply must be in kApplyMask. |
56 void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) { | 56 void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) { |
57 bool flush_icache = icache_flush_mode != SKIP_ICACHE_FLUSH; | 57 bool flush_icache = icache_flush_mode != SKIP_ICACHE_FLUSH; |
58 if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_)) { | 58 if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_)) { |
59 int32_t* p = reinterpret_cast<int32_t*>(pc_); | 59 int32_t* p = reinterpret_cast<int32_t*>(pc_); |
60 *p -= delta; // Relocate entry. | 60 *p -= delta; // Relocate entry. |
61 if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t)); | 61 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); |
62 } else if (rmode_ == CODE_AGE_SEQUENCE) { | 62 } else if (rmode_ == CODE_AGE_SEQUENCE) { |
63 if (*pc_ == kCallOpcode) { | 63 if (*pc_ == kCallOpcode) { |
64 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | 64 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); |
65 *p -= delta; // Relocate entry. | 65 *p -= delta; // Relocate entry. |
66 if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t)); | 66 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); |
67 } | 67 } |
68 } else if (rmode_ == JS_RETURN && IsPatchedReturnSequence()) { | 68 } else if (rmode_ == JS_RETURN && IsPatchedReturnSequence()) { |
69 // Special handling of js_return when a break point is set (call | 69 // Special handling of js_return when a break point is set (call |
70 // instruction has been inserted). | 70 // instruction has been inserted). |
71 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | 71 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); |
72 *p -= delta; // Relocate entry. | 72 *p -= delta; // Relocate entry. |
73 if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t)); | 73 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); |
74 } else if (rmode_ == DEBUG_BREAK_SLOT && IsPatchedDebugBreakSlotSequence()) { | 74 } else if (rmode_ == DEBUG_BREAK_SLOT && IsPatchedDebugBreakSlotSequence()) { |
75 // Special handling of a debug break slot when a break point is set (call | 75 // Special handling of a debug break slot when a break point is set (call |
76 // instruction has been inserted). | 76 // instruction has been inserted). |
77 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | 77 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); |
78 *p -= delta; // Relocate entry. | 78 *p -= delta; // Relocate entry. |
79 if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t)); | 79 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); |
80 } else if (IsInternalReference(rmode_)) { | 80 } else if (IsInternalReference(rmode_)) { |
81 // absolute code pointer inside code object moves with the code object. | 81 // absolute code pointer inside code object moves with the code object. |
82 int32_t* p = reinterpret_cast<int32_t*>(pc_); | 82 int32_t* p = reinterpret_cast<int32_t*>(pc_); |
83 *p += delta; // Relocate entry. | 83 *p += delta; // Relocate entry. |
84 if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t)); | 84 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); |
85 } | 85 } |
86 } | 86 } |
87 | 87 |
88 | 88 |
89 Address RelocInfo::target_address() { | 89 Address RelocInfo::target_address() { |
90 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 90 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
91 return Assembler::target_address_at(pc_, host_); | 91 return Assembler::target_address_at(pc_, host_); |
92 } | 92 } |
93 | 93 |
94 | 94 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 } | 138 } |
139 | 139 |
140 | 140 |
141 void RelocInfo::set_target_object(Object* target, | 141 void RelocInfo::set_target_object(Object* target, |
142 WriteBarrierMode write_barrier_mode, | 142 WriteBarrierMode write_barrier_mode, |
143 ICacheFlushMode icache_flush_mode) { | 143 ICacheFlushMode icache_flush_mode) { |
144 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 144 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
145 ASSERT(!target->IsConsString()); | 145 ASSERT(!target->IsConsString()); |
146 Memory::Object_at(pc_) = target; | 146 Memory::Object_at(pc_) = target; |
147 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 147 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
148 CPU::FlushICache(pc_, sizeof(Address)); | 148 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
149 } | 149 } |
150 if (write_barrier_mode == UPDATE_WRITE_BARRIER && | 150 if (write_barrier_mode == UPDATE_WRITE_BARRIER && |
151 host() != NULL && | 151 host() != NULL && |
152 target->IsHeapObject()) { | 152 target->IsHeapObject()) { |
153 host()->GetHeap()->incremental_marking()->RecordWrite( | 153 host()->GetHeap()->incremental_marking()->RecordWrite( |
154 host(), &Memory::Object_at(pc_), HeapObject::cast(target)); | 154 host(), &Memory::Object_at(pc_), HeapObject::cast(target)); |
155 } | 155 } |
156 } | 156 } |
157 | 157 |
158 | 158 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 } | 191 } |
192 | 192 |
193 | 193 |
194 void RelocInfo::set_target_cell(Cell* cell, | 194 void RelocInfo::set_target_cell(Cell* cell, |
195 WriteBarrierMode write_barrier_mode, | 195 WriteBarrierMode write_barrier_mode, |
196 ICacheFlushMode icache_flush_mode) { | 196 ICacheFlushMode icache_flush_mode) { |
197 ASSERT(rmode_ == RelocInfo::CELL); | 197 ASSERT(rmode_ == RelocInfo::CELL); |
198 Address address = cell->address() + Cell::kValueOffset; | 198 Address address = cell->address() + Cell::kValueOffset; |
199 Memory::Address_at(pc_) = address; | 199 Memory::Address_at(pc_) = address; |
200 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 200 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
201 CPU::FlushICache(pc_, sizeof(Address)); | 201 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
202 } | 202 } |
203 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { | 203 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { |
204 // TODO(1550) We are passing NULL as a slot because cell can never be on | 204 // TODO(1550) We are passing NULL as a slot because cell can never be on |
205 // evacuation candidate. | 205 // evacuation candidate. |
206 host()->GetHeap()->incremental_marking()->RecordWrite( | 206 host()->GetHeap()->incremental_marking()->RecordWrite( |
207 host(), NULL, cell); | 207 host(), NULL, cell); |
208 } | 208 } |
209 } | 209 } |
210 | 210 |
211 | 211 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 | 288 |
289 bool RelocInfo::IsPatchedDebugBreakSlotSequence() { | 289 bool RelocInfo::IsPatchedDebugBreakSlotSequence() { |
290 return !Assembler::IsNop(pc()); | 290 return !Assembler::IsNop(pc()); |
291 } | 291 } |
292 | 292 |
293 | 293 |
294 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { | 294 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { |
295 RelocInfo::Mode mode = rmode(); | 295 RelocInfo::Mode mode = rmode(); |
296 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 296 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
297 visitor->VisitEmbeddedPointer(this); | 297 visitor->VisitEmbeddedPointer(this); |
298 CPU::FlushICache(pc_, sizeof(Address)); | 298 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
299 } else if (RelocInfo::IsCodeTarget(mode)) { | 299 } else if (RelocInfo::IsCodeTarget(mode)) { |
300 visitor->VisitCodeTarget(this); | 300 visitor->VisitCodeTarget(this); |
301 } else if (mode == RelocInfo::CELL) { | 301 } else if (mode == RelocInfo::CELL) { |
302 visitor->VisitCell(this); | 302 visitor->VisitCell(this); |
303 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 303 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
304 visitor->VisitExternalReference(this); | 304 visitor->VisitExternalReference(this); |
305 CPU::FlushICache(pc_, sizeof(Address)); | 305 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
306 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 306 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
307 visitor->VisitCodeAgeSequence(this); | 307 visitor->VisitCodeAgeSequence(this); |
308 } else if (((RelocInfo::IsJSReturn(mode) && | 308 } else if (((RelocInfo::IsJSReturn(mode) && |
309 IsPatchedReturnSequence()) || | 309 IsPatchedReturnSequence()) || |
310 (RelocInfo::IsDebugBreakSlot(mode) && | 310 (RelocInfo::IsDebugBreakSlot(mode) && |
311 IsPatchedDebugBreakSlotSequence())) && | 311 IsPatchedDebugBreakSlotSequence())) && |
312 isolate->debug()->has_break_points()) { | 312 isolate->debug()->has_break_points()) { |
313 visitor->VisitDebugTarget(this); | 313 visitor->VisitDebugTarget(this); |
314 } else if (IsRuntimeEntry(mode)) { | 314 } else if (IsRuntimeEntry(mode)) { |
315 visitor->VisitRuntimeEntry(this); | 315 visitor->VisitRuntimeEntry(this); |
316 } | 316 } |
317 } | 317 } |
318 | 318 |
319 | 319 |
320 template<typename StaticVisitor> | 320 template<typename StaticVisitor> |
321 void RelocInfo::Visit(Heap* heap) { | 321 void RelocInfo::Visit(Heap* heap) { |
322 RelocInfo::Mode mode = rmode(); | 322 RelocInfo::Mode mode = rmode(); |
323 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 323 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
324 StaticVisitor::VisitEmbeddedPointer(heap, this); | 324 StaticVisitor::VisitEmbeddedPointer(heap, this); |
325 CPU::FlushICache(pc_, sizeof(Address)); | 325 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
326 } else if (RelocInfo::IsCodeTarget(mode)) { | 326 } else if (RelocInfo::IsCodeTarget(mode)) { |
327 StaticVisitor::VisitCodeTarget(heap, this); | 327 StaticVisitor::VisitCodeTarget(heap, this); |
328 } else if (mode == RelocInfo::CELL) { | 328 } else if (mode == RelocInfo::CELL) { |
329 StaticVisitor::VisitCell(heap, this); | 329 StaticVisitor::VisitCell(heap, this); |
330 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 330 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
331 StaticVisitor::VisitExternalReference(this); | 331 StaticVisitor::VisitExternalReference(this); |
332 CPU::FlushICache(pc_, sizeof(Address)); | 332 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
333 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 333 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
334 StaticVisitor::VisitCodeAgeSequence(heap, this); | 334 StaticVisitor::VisitCodeAgeSequence(heap, this); |
335 } else if (heap->isolate()->debug()->has_break_points() && | 335 } else if (heap->isolate()->debug()->has_break_points() && |
336 ((RelocInfo::IsJSReturn(mode) && | 336 ((RelocInfo::IsJSReturn(mode) && |
337 IsPatchedReturnSequence()) || | 337 IsPatchedReturnSequence()) || |
338 (RelocInfo::IsDebugBreakSlot(mode) && | 338 (RelocInfo::IsDebugBreakSlot(mode) && |
339 IsPatchedDebugBreakSlotSequence()))) { | 339 IsPatchedDebugBreakSlotSequence()))) { |
340 StaticVisitor::VisitDebugTarget(heap, this); | 340 StaticVisitor::VisitDebugTarget(heap, this); |
341 } else if (IsRuntimeEntry(mode)) { | 341 } else if (IsRuntimeEntry(mode)) { |
342 StaticVisitor::VisitRuntimeEntry(this); | 342 StaticVisitor::VisitRuntimeEntry(this); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 } | 467 } |
468 | 468 |
469 | 469 |
470 void Assembler::set_target_address_at(Address pc, | 470 void Assembler::set_target_address_at(Address pc, |
471 ConstantPoolArray* constant_pool, | 471 ConstantPoolArray* constant_pool, |
472 Address target, | 472 Address target, |
473 ICacheFlushMode icache_flush_mode) { | 473 ICacheFlushMode icache_flush_mode) { |
474 int32_t* p = reinterpret_cast<int32_t*>(pc); | 474 int32_t* p = reinterpret_cast<int32_t*>(pc); |
475 *p = target - (pc + sizeof(int32_t)); | 475 *p = target - (pc + sizeof(int32_t)); |
476 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 476 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
477 CPU::FlushICache(p, sizeof(int32_t)); | 477 CpuFeatures::FlushICache(p, sizeof(int32_t)); |
478 } | 478 } |
479 } | 479 } |
480 | 480 |
481 | 481 |
482 Address Assembler::target_address_from_return_address(Address pc) { | 482 Address Assembler::target_address_from_return_address(Address pc) { |
483 return pc - kCallTargetAddressOffset; | 483 return pc - kCallTargetAddressOffset; |
484 } | 484 } |
485 | 485 |
486 | 486 |
487 Displacement Assembler::disp_at(Label* L) { | 487 Displacement Assembler::disp_at(Label* L) { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 | 552 |
553 Operand::Operand(int32_t disp, RelocInfo::Mode rmode) { | 553 Operand::Operand(int32_t disp, RelocInfo::Mode rmode) { |
554 // [disp/r] | 554 // [disp/r] |
555 set_modrm(0, ebp); | 555 set_modrm(0, ebp); |
556 set_dispr(disp, rmode); | 556 set_dispr(disp, rmode); |
557 } | 557 } |
558 | 558 |
559 } } // namespace v8::internal | 559 } } // namespace v8::internal |
560 | 560 |
561 #endif // V8_X87_ASSEMBLER_X87_INL_H_ | 561 #endif // V8_X87_ASSEMBLER_X87_INL_H_ |
OLD | NEW |