| 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 |