OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_X64_ASSEMBLER_X64_INL_H_ | 5 #ifndef V8_X64_ASSEMBLER_X64_INL_H_ |
6 #define V8_X64_ASSEMBLER_X64_INL_H_ | 6 #define V8_X64_ASSEMBLER_X64_INL_H_ |
7 | 7 |
8 #include "src/x64/assembler-x64.h" | 8 #include "src/x64/assembler-x64.h" |
9 | 9 |
10 #include "src/cpu.h" | 10 #include "src/base/cpu.h" |
11 #include "src/debug.h" | 11 #include "src/debug.h" |
12 #include "src/v8memory.h" | 12 #include "src/v8memory.h" |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 | 16 |
17 bool CpuFeatures::SupportsCrankshaft() { return true; } | 17 bool CpuFeatures::SupportsCrankshaft() { return true; } |
18 | 18 |
19 | 19 |
20 // ----------------------------------------------------------------------------- | 20 // ----------------------------------------------------------------------------- |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 return Memory::int32_at(pc) + pc + 4; | 189 return Memory::int32_at(pc) + pc + 4; |
190 } | 190 } |
191 | 191 |
192 | 192 |
193 void Assembler::set_target_address_at(Address pc, | 193 void Assembler::set_target_address_at(Address pc, |
194 ConstantPoolArray* constant_pool, | 194 ConstantPoolArray* constant_pool, |
195 Address target, | 195 Address target, |
196 ICacheFlushMode icache_flush_mode) { | 196 ICacheFlushMode icache_flush_mode) { |
197 Memory::int32_at(pc) = static_cast<int32_t>(target - pc - 4); | 197 Memory::int32_at(pc) = static_cast<int32_t>(target - pc - 4); |
198 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 198 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
199 CPU::FlushICache(pc, sizeof(int32_t)); | 199 CpuFeatures::FlushICache(pc, sizeof(int32_t)); |
200 } | 200 } |
201 } | 201 } |
202 | 202 |
203 | 203 |
204 Address Assembler::target_address_from_return_address(Address pc) { | 204 Address Assembler::target_address_from_return_address(Address pc) { |
205 return pc - kCallTargetAddressOffset; | 205 return pc - kCallTargetAddressOffset; |
206 } | 206 } |
207 | 207 |
208 | 208 |
209 Handle<Object> Assembler::code_target_object_handle_at(Address pc) { | 209 Handle<Object> Assembler::code_target_object_handle_at(Address pc) { |
210 return code_targets_[Memory::int32_at(pc)]; | 210 return code_targets_[Memory::int32_at(pc)]; |
211 } | 211 } |
212 | 212 |
213 | 213 |
214 Address Assembler::runtime_entry_at(Address pc) { | 214 Address Assembler::runtime_entry_at(Address pc) { |
215 return Memory::int32_at(pc) + isolate()->code_range()->start(); | 215 return Memory::int32_at(pc) + isolate()->code_range()->start(); |
216 } | 216 } |
217 | 217 |
218 // ----------------------------------------------------------------------------- | 218 // ----------------------------------------------------------------------------- |
219 // Implementation of RelocInfo | 219 // Implementation of RelocInfo |
220 | 220 |
221 // The modes possibly affected by apply must be in kApplyMask. | 221 // The modes possibly affected by apply must be in kApplyMask. |
222 void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) { | 222 void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) { |
223 bool flush_icache = icache_flush_mode != SKIP_ICACHE_FLUSH; | 223 bool flush_icache = icache_flush_mode != SKIP_ICACHE_FLUSH; |
224 if (IsInternalReference(rmode_)) { | 224 if (IsInternalReference(rmode_)) { |
225 // absolute code pointer inside code object moves with the code object. | 225 // absolute code pointer inside code object moves with the code object. |
226 Memory::Address_at(pc_) += static_cast<int32_t>(delta); | 226 Memory::Address_at(pc_) += static_cast<int32_t>(delta); |
227 if (flush_icache) CPU::FlushICache(pc_, sizeof(Address)); | 227 if (flush_icache) CpuFeatures::FlushICache(pc_, sizeof(Address)); |
228 } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { | 228 } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { |
229 Memory::int32_at(pc_) -= static_cast<int32_t>(delta); | 229 Memory::int32_at(pc_) -= static_cast<int32_t>(delta); |
230 if (flush_icache) CPU::FlushICache(pc_, sizeof(int32_t)); | 230 if (flush_icache) CpuFeatures::FlushICache(pc_, sizeof(int32_t)); |
231 } else if (rmode_ == CODE_AGE_SEQUENCE) { | 231 } else if (rmode_ == CODE_AGE_SEQUENCE) { |
232 if (*pc_ == kCallOpcode) { | 232 if (*pc_ == kCallOpcode) { |
233 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | 233 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); |
234 *p -= static_cast<int32_t>(delta); // Relocate entry. | 234 *p -= static_cast<int32_t>(delta); // Relocate entry. |
235 if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t)); | 235 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); |
236 } | 236 } |
237 } | 237 } |
238 } | 238 } |
239 | 239 |
240 | 240 |
241 Address RelocInfo::target_address() { | 241 Address RelocInfo::target_address() { |
242 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 242 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
243 return Assembler::target_address_at(pc_, host_); | 243 return Assembler::target_address_at(pc_, host_); |
244 } | 244 } |
245 | 245 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 } | 303 } |
304 | 304 |
305 | 305 |
306 void RelocInfo::set_target_object(Object* target, | 306 void RelocInfo::set_target_object(Object* target, |
307 WriteBarrierMode write_barrier_mode, | 307 WriteBarrierMode write_barrier_mode, |
308 ICacheFlushMode icache_flush_mode) { | 308 ICacheFlushMode icache_flush_mode) { |
309 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 309 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
310 ASSERT(!target->IsConsString()); | 310 ASSERT(!target->IsConsString()); |
311 Memory::Object_at(pc_) = target; | 311 Memory::Object_at(pc_) = target; |
312 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 312 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
313 CPU::FlushICache(pc_, sizeof(Address)); | 313 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
314 } | 314 } |
315 if (write_barrier_mode == UPDATE_WRITE_BARRIER && | 315 if (write_barrier_mode == UPDATE_WRITE_BARRIER && |
316 host() != NULL && | 316 host() != NULL && |
317 target->IsHeapObject()) { | 317 target->IsHeapObject()) { |
318 host()->GetHeap()->incremental_marking()->RecordWrite( | 318 host()->GetHeap()->incremental_marking()->RecordWrite( |
319 host(), &Memory::Object_at(pc_), HeapObject::cast(target)); | 319 host(), &Memory::Object_at(pc_), HeapObject::cast(target)); |
320 } | 320 } |
321 } | 321 } |
322 | 322 |
323 | 323 |
(...skipping 26 matching lines...) Expand all Loading... |
350 } | 350 } |
351 | 351 |
352 | 352 |
353 void RelocInfo::set_target_cell(Cell* cell, | 353 void RelocInfo::set_target_cell(Cell* cell, |
354 WriteBarrierMode write_barrier_mode, | 354 WriteBarrierMode write_barrier_mode, |
355 ICacheFlushMode icache_flush_mode) { | 355 ICacheFlushMode icache_flush_mode) { |
356 ASSERT(rmode_ == RelocInfo::CELL); | 356 ASSERT(rmode_ == RelocInfo::CELL); |
357 Address address = cell->address() + Cell::kValueOffset; | 357 Address address = cell->address() + Cell::kValueOffset; |
358 Memory::Address_at(pc_) = address; | 358 Memory::Address_at(pc_) = address; |
359 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 359 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
360 CPU::FlushICache(pc_, sizeof(Address)); | 360 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
361 } | 361 } |
362 if (write_barrier_mode == UPDATE_WRITE_BARRIER && | 362 if (write_barrier_mode == UPDATE_WRITE_BARRIER && |
363 host() != NULL) { | 363 host() != NULL) { |
364 // TODO(1550) We are passing NULL as a slot because cell can never be on | 364 // TODO(1550) We are passing NULL as a slot because cell can never be on |
365 // evacuation candidate. | 365 // evacuation candidate. |
366 host()->GetHeap()->incremental_marking()->RecordWrite( | 366 host()->GetHeap()->incremental_marking()->RecordWrite( |
367 host(), NULL, cell); | 367 host(), NULL, cell); |
368 } | 368 } |
369 } | 369 } |
370 | 370 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 return Memory::Address_at( | 428 return Memory::Address_at( |
429 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset); | 429 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset); |
430 } | 430 } |
431 | 431 |
432 | 432 |
433 void RelocInfo::set_call_address(Address target) { | 433 void RelocInfo::set_call_address(Address target) { |
434 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 434 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
435 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 435 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
436 Memory::Address_at(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset) = | 436 Memory::Address_at(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset) = |
437 target; | 437 target; |
438 CPU::FlushICache(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset, | 438 CpuFeatures::FlushICache( |
439 sizeof(Address)); | 439 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset, sizeof(Address)); |
440 if (host() != NULL) { | 440 if (host() != NULL) { |
441 Object* target_code = Code::GetCodeFromTargetAddress(target); | 441 Object* target_code = Code::GetCodeFromTargetAddress(target); |
442 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 442 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
443 host(), this, HeapObject::cast(target_code)); | 443 host(), this, HeapObject::cast(target_code)); |
444 } | 444 } |
445 } | 445 } |
446 | 446 |
447 | 447 |
448 Object* RelocInfo::call_object() { | 448 Object* RelocInfo::call_object() { |
449 return *call_object_address(); | 449 return *call_object_address(); |
(...skipping 10 matching lines...) Expand all Loading... |
460 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 460 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
461 return reinterpret_cast<Object**>( | 461 return reinterpret_cast<Object**>( |
462 pc_ + Assembler::kPatchReturnSequenceAddressOffset); | 462 pc_ + Assembler::kPatchReturnSequenceAddressOffset); |
463 } | 463 } |
464 | 464 |
465 | 465 |
466 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { | 466 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { |
467 RelocInfo::Mode mode = rmode(); | 467 RelocInfo::Mode mode = rmode(); |
468 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 468 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
469 visitor->VisitEmbeddedPointer(this); | 469 visitor->VisitEmbeddedPointer(this); |
470 CPU::FlushICache(pc_, sizeof(Address)); | 470 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
471 } else if (RelocInfo::IsCodeTarget(mode)) { | 471 } else if (RelocInfo::IsCodeTarget(mode)) { |
472 visitor->VisitCodeTarget(this); | 472 visitor->VisitCodeTarget(this); |
473 } else if (mode == RelocInfo::CELL) { | 473 } else if (mode == RelocInfo::CELL) { |
474 visitor->VisitCell(this); | 474 visitor->VisitCell(this); |
475 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 475 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
476 visitor->VisitExternalReference(this); | 476 visitor->VisitExternalReference(this); |
477 CPU::FlushICache(pc_, sizeof(Address)); | 477 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
478 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 478 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
479 visitor->VisitCodeAgeSequence(this); | 479 visitor->VisitCodeAgeSequence(this); |
480 } else if (((RelocInfo::IsJSReturn(mode) && | 480 } else if (((RelocInfo::IsJSReturn(mode) && |
481 IsPatchedReturnSequence()) || | 481 IsPatchedReturnSequence()) || |
482 (RelocInfo::IsDebugBreakSlot(mode) && | 482 (RelocInfo::IsDebugBreakSlot(mode) && |
483 IsPatchedDebugBreakSlotSequence())) && | 483 IsPatchedDebugBreakSlotSequence())) && |
484 isolate->debug()->has_break_points()) { | 484 isolate->debug()->has_break_points()) { |
485 visitor->VisitDebugTarget(this); | 485 visitor->VisitDebugTarget(this); |
486 } else if (RelocInfo::IsRuntimeEntry(mode)) { | 486 } else if (RelocInfo::IsRuntimeEntry(mode)) { |
487 visitor->VisitRuntimeEntry(this); | 487 visitor->VisitRuntimeEntry(this); |
488 } | 488 } |
489 } | 489 } |
490 | 490 |
491 | 491 |
492 template<typename StaticVisitor> | 492 template<typename StaticVisitor> |
493 void RelocInfo::Visit(Heap* heap) { | 493 void RelocInfo::Visit(Heap* heap) { |
494 RelocInfo::Mode mode = rmode(); | 494 RelocInfo::Mode mode = rmode(); |
495 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 495 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
496 StaticVisitor::VisitEmbeddedPointer(heap, this); | 496 StaticVisitor::VisitEmbeddedPointer(heap, this); |
497 CPU::FlushICache(pc_, sizeof(Address)); | 497 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
498 } else if (RelocInfo::IsCodeTarget(mode)) { | 498 } else if (RelocInfo::IsCodeTarget(mode)) { |
499 StaticVisitor::VisitCodeTarget(heap, this); | 499 StaticVisitor::VisitCodeTarget(heap, this); |
500 } else if (mode == RelocInfo::CELL) { | 500 } else if (mode == RelocInfo::CELL) { |
501 StaticVisitor::VisitCell(heap, this); | 501 StaticVisitor::VisitCell(heap, this); |
502 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 502 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
503 StaticVisitor::VisitExternalReference(this); | 503 StaticVisitor::VisitExternalReference(this); |
504 CPU::FlushICache(pc_, sizeof(Address)); | 504 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
505 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 505 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
506 StaticVisitor::VisitCodeAgeSequence(heap, this); | 506 StaticVisitor::VisitCodeAgeSequence(heap, this); |
507 } else if (heap->isolate()->debug()->has_break_points() && | 507 } else if (heap->isolate()->debug()->has_break_points() && |
508 ((RelocInfo::IsJSReturn(mode) && | 508 ((RelocInfo::IsJSReturn(mode) && |
509 IsPatchedReturnSequence()) || | 509 IsPatchedReturnSequence()) || |
510 (RelocInfo::IsDebugBreakSlot(mode) && | 510 (RelocInfo::IsDebugBreakSlot(mode) && |
511 IsPatchedDebugBreakSlotSequence()))) { | 511 IsPatchedDebugBreakSlotSequence()))) { |
512 StaticVisitor::VisitDebugTarget(heap, this); | 512 StaticVisitor::VisitDebugTarget(heap, this); |
513 } else if (RelocInfo::IsRuntimeEntry(mode)) { | 513 } else if (RelocInfo::IsRuntimeEntry(mode)) { |
514 StaticVisitor::VisitRuntimeEntry(this); | 514 StaticVisitor::VisitRuntimeEntry(this); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 ASSERT(len_ == 1 || len_ == 2); | 550 ASSERT(len_ == 1 || len_ == 2); |
551 int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); | 551 int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); |
552 *p = disp; | 552 *p = disp; |
553 len_ += sizeof(int32_t); | 553 len_ += sizeof(int32_t); |
554 } | 554 } |
555 | 555 |
556 | 556 |
557 } } // namespace v8::internal | 557 } } // namespace v8::internal |
558 | 558 |
559 #endif // V8_X64_ASSEMBLER_X64_INL_H_ | 559 #endif // V8_X64_ASSEMBLER_X64_INL_H_ |
OLD | NEW |