| 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/base/cpu.h" | 10 #include "src/base/cpu.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 | 50 |
| 51 void Assembler::emitw(uint16_t x) { | 51 void Assembler::emitw(uint16_t x) { |
| 52 Memory::uint16_at(pc_) = x; | 52 Memory::uint16_at(pc_) = x; |
| 53 pc_ += sizeof(uint16_t); | 53 pc_ += sizeof(uint16_t); |
| 54 } | 54 } |
| 55 | 55 |
| 56 | 56 |
| 57 void Assembler::emit_code_target(Handle<Code> target, | 57 void Assembler::emit_code_target(Handle<Code> target, |
| 58 RelocInfo::Mode rmode, | 58 RelocInfo::Mode rmode, |
| 59 TypeFeedbackId ast_id) { | 59 TypeFeedbackId ast_id) { |
| 60 ASSERT(RelocInfo::IsCodeTarget(rmode) || | 60 DCHECK(RelocInfo::IsCodeTarget(rmode) || |
| 61 rmode == RelocInfo::CODE_AGE_SEQUENCE); | 61 rmode == RelocInfo::CODE_AGE_SEQUENCE); |
| 62 if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) { | 62 if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) { |
| 63 RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, ast_id.ToInt()); | 63 RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, ast_id.ToInt()); |
| 64 } else { | 64 } else { |
| 65 RecordRelocInfo(rmode); | 65 RecordRelocInfo(rmode); |
| 66 } | 66 } |
| 67 int current = code_targets_.length(); | 67 int current = code_targets_.length(); |
| 68 if (current > 0 && code_targets_.last().is_identical_to(target)) { | 68 if (current > 0 && code_targets_.last().is_identical_to(target)) { |
| 69 // Optimization if we keep jumping to the same code target. | 69 // Optimization if we keep jumping to the same code target. |
| 70 emitl(current - 1); | 70 emitl(current - 1); |
| 71 } else { | 71 } else { |
| 72 code_targets_.Add(target); | 72 code_targets_.Add(target); |
| 73 emitl(current); | 73 emitl(current); |
| 74 } | 74 } |
| 75 } | 75 } |
| 76 | 76 |
| 77 | 77 |
| 78 void Assembler::emit_runtime_entry(Address entry, RelocInfo::Mode rmode) { | 78 void Assembler::emit_runtime_entry(Address entry, RelocInfo::Mode rmode) { |
| 79 ASSERT(RelocInfo::IsRuntimeEntry(rmode)); | 79 DCHECK(RelocInfo::IsRuntimeEntry(rmode)); |
| 80 RecordRelocInfo(rmode); | 80 RecordRelocInfo(rmode); |
| 81 emitl(static_cast<uint32_t>(entry - isolate()->code_range()->start())); | 81 emitl(static_cast<uint32_t>(entry - isolate()->code_range()->start())); |
| 82 } | 82 } |
| 83 | 83 |
| 84 | 84 |
| 85 void Assembler::emit_rex_64(Register reg, Register rm_reg) { | 85 void Assembler::emit_rex_64(Register reg, Register rm_reg) { |
| 86 emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit()); | 86 emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit()); |
| 87 } | 87 } |
| 88 | 88 |
| 89 | 89 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 101 emit(0x48 | reg.high_bit() << 2 | op.rex_); | 101 emit(0x48 | reg.high_bit() << 2 | op.rex_); |
| 102 } | 102 } |
| 103 | 103 |
| 104 | 104 |
| 105 void Assembler::emit_rex_64(XMMRegister reg, const Operand& op) { | 105 void Assembler::emit_rex_64(XMMRegister reg, const Operand& op) { |
| 106 emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_); | 106 emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_); |
| 107 } | 107 } |
| 108 | 108 |
| 109 | 109 |
| 110 void Assembler::emit_rex_64(Register rm_reg) { | 110 void Assembler::emit_rex_64(Register rm_reg) { |
| 111 ASSERT_EQ(rm_reg.code() & 0xf, rm_reg.code()); | 111 DCHECK_EQ(rm_reg.code() & 0xf, rm_reg.code()); |
| 112 emit(0x48 | rm_reg.high_bit()); | 112 emit(0x48 | rm_reg.high_bit()); |
| 113 } | 113 } |
| 114 | 114 |
| 115 | 115 |
| 116 void Assembler::emit_rex_64(const Operand& op) { | 116 void Assembler::emit_rex_64(const Operand& op) { |
| 117 emit(0x48 | op.rex_); | 117 emit(0x48 | op.rex_); |
| 118 } | 118 } |
| 119 | 119 |
| 120 | 120 |
| 121 void Assembler::emit_rex_32(Register reg, Register rm_reg) { | 121 void Assembler::emit_rex_32(Register reg, Register rm_reg) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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) CpuFeatures::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 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
| 243 return Assembler::target_address_at(pc_, host_); | 243 return Assembler::target_address_at(pc_, host_); |
| 244 } | 244 } |
| 245 | 245 |
| 246 | 246 |
| 247 Address RelocInfo::target_address_address() { | 247 Address RelocInfo::target_address_address() { |
| 248 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) | 248 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) |
| 249 || rmode_ == EMBEDDED_OBJECT | 249 || rmode_ == EMBEDDED_OBJECT |
| 250 || rmode_ == EXTERNAL_REFERENCE); | 250 || rmode_ == EXTERNAL_REFERENCE); |
| 251 return reinterpret_cast<Address>(pc_); | 251 return reinterpret_cast<Address>(pc_); |
| 252 } | 252 } |
| 253 | 253 |
| 254 | 254 |
| 255 Address RelocInfo::constant_pool_entry_address() { | 255 Address RelocInfo::constant_pool_entry_address() { |
| 256 UNREACHABLE(); | 256 UNREACHABLE(); |
| 257 return NULL; | 257 return NULL; |
| 258 } | 258 } |
| 259 | 259 |
| 260 | 260 |
| 261 int RelocInfo::target_address_size() { | 261 int RelocInfo::target_address_size() { |
| 262 if (IsCodedSpecially()) { | 262 if (IsCodedSpecially()) { |
| 263 return Assembler::kSpecialTargetSize; | 263 return Assembler::kSpecialTargetSize; |
| 264 } else { | 264 } else { |
| 265 return kPointerSize; | 265 return kPointerSize; |
| 266 } | 266 } |
| 267 } | 267 } |
| 268 | 268 |
| 269 | 269 |
| 270 void RelocInfo::set_target_address(Address target, | 270 void RelocInfo::set_target_address(Address target, |
| 271 WriteBarrierMode write_barrier_mode, | 271 WriteBarrierMode write_barrier_mode, |
| 272 ICacheFlushMode icache_flush_mode) { | 272 ICacheFlushMode icache_flush_mode) { |
| 273 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 273 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
| 274 Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode); | 274 Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode); |
| 275 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL && | 275 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL && |
| 276 IsCodeTarget(rmode_)) { | 276 IsCodeTarget(rmode_)) { |
| 277 Object* target_code = Code::GetCodeFromTargetAddress(target); | 277 Object* target_code = Code::GetCodeFromTargetAddress(target); |
| 278 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 278 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
| 279 host(), this, HeapObject::cast(target_code)); | 279 host(), this, HeapObject::cast(target_code)); |
| 280 } | 280 } |
| 281 } | 281 } |
| 282 | 282 |
| 283 | 283 |
| 284 Object* RelocInfo::target_object() { | 284 Object* RelocInfo::target_object() { |
| 285 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 285 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
| 286 return Memory::Object_at(pc_); | 286 return Memory::Object_at(pc_); |
| 287 } | 287 } |
| 288 | 288 |
| 289 | 289 |
| 290 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { | 290 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { |
| 291 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 291 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
| 292 if (rmode_ == EMBEDDED_OBJECT) { | 292 if (rmode_ == EMBEDDED_OBJECT) { |
| 293 return Memory::Object_Handle_at(pc_); | 293 return Memory::Object_Handle_at(pc_); |
| 294 } else { | 294 } else { |
| 295 return origin->code_target_object_handle_at(pc_); | 295 return origin->code_target_object_handle_at(pc_); |
| 296 } | 296 } |
| 297 } | 297 } |
| 298 | 298 |
| 299 | 299 |
| 300 Address RelocInfo::target_reference() { | 300 Address RelocInfo::target_reference() { |
| 301 ASSERT(rmode_ == RelocInfo::EXTERNAL_REFERENCE); | 301 DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE); |
| 302 return Memory::Address_at(pc_); | 302 return Memory::Address_at(pc_); |
| 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 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
| 310 Memory::Object_at(pc_) = target; | 310 Memory::Object_at(pc_) = target; |
| 311 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 311 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
| 312 CpuFeatures::FlushICache(pc_, sizeof(Address)); | 312 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
| 313 } | 313 } |
| 314 if (write_barrier_mode == UPDATE_WRITE_BARRIER && | 314 if (write_barrier_mode == UPDATE_WRITE_BARRIER && |
| 315 host() != NULL && | 315 host() != NULL && |
| 316 target->IsHeapObject()) { | 316 target->IsHeapObject()) { |
| 317 host()->GetHeap()->incremental_marking()->RecordWrite( | 317 host()->GetHeap()->incremental_marking()->RecordWrite( |
| 318 host(), &Memory::Object_at(pc_), HeapObject::cast(target)); | 318 host(), &Memory::Object_at(pc_), HeapObject::cast(target)); |
| 319 } | 319 } |
| 320 } | 320 } |
| 321 | 321 |
| 322 | 322 |
| 323 Address RelocInfo::target_runtime_entry(Assembler* origin) { | 323 Address RelocInfo::target_runtime_entry(Assembler* origin) { |
| 324 ASSERT(IsRuntimeEntry(rmode_)); | 324 DCHECK(IsRuntimeEntry(rmode_)); |
| 325 return origin->runtime_entry_at(pc_); | 325 return origin->runtime_entry_at(pc_); |
| 326 } | 326 } |
| 327 | 327 |
| 328 | 328 |
| 329 void RelocInfo::set_target_runtime_entry(Address target, | 329 void RelocInfo::set_target_runtime_entry(Address target, |
| 330 WriteBarrierMode write_barrier_mode, | 330 WriteBarrierMode write_barrier_mode, |
| 331 ICacheFlushMode icache_flush_mode) { | 331 ICacheFlushMode icache_flush_mode) { |
| 332 ASSERT(IsRuntimeEntry(rmode_)); | 332 DCHECK(IsRuntimeEntry(rmode_)); |
| 333 if (target_address() != target) { | 333 if (target_address() != target) { |
| 334 set_target_address(target, write_barrier_mode, icache_flush_mode); | 334 set_target_address(target, write_barrier_mode, icache_flush_mode); |
| 335 } | 335 } |
| 336 } | 336 } |
| 337 | 337 |
| 338 | 338 |
| 339 Handle<Cell> RelocInfo::target_cell_handle() { | 339 Handle<Cell> RelocInfo::target_cell_handle() { |
| 340 ASSERT(rmode_ == RelocInfo::CELL); | 340 DCHECK(rmode_ == RelocInfo::CELL); |
| 341 Address address = Memory::Address_at(pc_); | 341 Address address = Memory::Address_at(pc_); |
| 342 return Handle<Cell>(reinterpret_cast<Cell**>(address)); | 342 return Handle<Cell>(reinterpret_cast<Cell**>(address)); |
| 343 } | 343 } |
| 344 | 344 |
| 345 | 345 |
| 346 Cell* RelocInfo::target_cell() { | 346 Cell* RelocInfo::target_cell() { |
| 347 ASSERT(rmode_ == RelocInfo::CELL); | 347 DCHECK(rmode_ == RelocInfo::CELL); |
| 348 return Cell::FromValueAddress(Memory::Address_at(pc_)); | 348 return Cell::FromValueAddress(Memory::Address_at(pc_)); |
| 349 } | 349 } |
| 350 | 350 |
| 351 | 351 |
| 352 void RelocInfo::set_target_cell(Cell* cell, | 352 void RelocInfo::set_target_cell(Cell* cell, |
| 353 WriteBarrierMode write_barrier_mode, | 353 WriteBarrierMode write_barrier_mode, |
| 354 ICacheFlushMode icache_flush_mode) { | 354 ICacheFlushMode icache_flush_mode) { |
| 355 ASSERT(rmode_ == RelocInfo::CELL); | 355 DCHECK(rmode_ == RelocInfo::CELL); |
| 356 Address address = cell->address() + Cell::kValueOffset; | 356 Address address = cell->address() + Cell::kValueOffset; |
| 357 Memory::Address_at(pc_) = address; | 357 Memory::Address_at(pc_) = address; |
| 358 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 358 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
| 359 CpuFeatures::FlushICache(pc_, sizeof(Address)); | 359 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
| 360 } | 360 } |
| 361 if (write_barrier_mode == UPDATE_WRITE_BARRIER && | 361 if (write_barrier_mode == UPDATE_WRITE_BARRIER && |
| 362 host() != NULL) { | 362 host() != NULL) { |
| 363 // TODO(1550) We are passing NULL as a slot because cell can never be on | 363 // TODO(1550) We are passing NULL as a slot because cell can never be on |
| 364 // evacuation candidate. | 364 // evacuation candidate. |
| 365 host()->GetHeap()->incremental_marking()->RecordWrite( | 365 host()->GetHeap()->incremental_marking()->RecordWrite( |
| (...skipping 25 matching lines...) Expand all Loading... |
| 391 0xCC; | 391 0xCC; |
| 392 } | 392 } |
| 393 | 393 |
| 394 | 394 |
| 395 bool RelocInfo::IsPatchedDebugBreakSlotSequence() { | 395 bool RelocInfo::IsPatchedDebugBreakSlotSequence() { |
| 396 return !Assembler::IsNop(pc()); | 396 return !Assembler::IsNop(pc()); |
| 397 } | 397 } |
| 398 | 398 |
| 399 | 399 |
| 400 Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { | 400 Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { |
| 401 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 401 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
| 402 ASSERT(*pc_ == kCallOpcode); | 402 DCHECK(*pc_ == kCallOpcode); |
| 403 return origin->code_target_object_handle_at(pc_ + 1); | 403 return origin->code_target_object_handle_at(pc_ + 1); |
| 404 } | 404 } |
| 405 | 405 |
| 406 | 406 |
| 407 Code* RelocInfo::code_age_stub() { | 407 Code* RelocInfo::code_age_stub() { |
| 408 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 408 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
| 409 ASSERT(*pc_ == kCallOpcode); | 409 DCHECK(*pc_ == kCallOpcode); |
| 410 return Code::GetCodeFromTargetAddress( | 410 return Code::GetCodeFromTargetAddress( |
| 411 Assembler::target_address_at(pc_ + 1, host_)); | 411 Assembler::target_address_at(pc_ + 1, host_)); |
| 412 } | 412 } |
| 413 | 413 |
| 414 | 414 |
| 415 void RelocInfo::set_code_age_stub(Code* stub, | 415 void RelocInfo::set_code_age_stub(Code* stub, |
| 416 ICacheFlushMode icache_flush_mode) { | 416 ICacheFlushMode icache_flush_mode) { |
| 417 ASSERT(*pc_ == kCallOpcode); | 417 DCHECK(*pc_ == kCallOpcode); |
| 418 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 418 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
| 419 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), | 419 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), |
| 420 icache_flush_mode); | 420 icache_flush_mode); |
| 421 } | 421 } |
| 422 | 422 |
| 423 | 423 |
| 424 Address RelocInfo::call_address() { | 424 Address RelocInfo::call_address() { |
| 425 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 425 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
| 426 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 426 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
| 427 return Memory::Address_at( | 427 return Memory::Address_at( |
| 428 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset); | 428 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset); |
| 429 } | 429 } |
| 430 | 430 |
| 431 | 431 |
| 432 void RelocInfo::set_call_address(Address target) { | 432 void RelocInfo::set_call_address(Address target) { |
| 433 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 433 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
| 434 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 434 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
| 435 Memory::Address_at(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset) = | 435 Memory::Address_at(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset) = |
| 436 target; | 436 target; |
| 437 CpuFeatures::FlushICache( | 437 CpuFeatures::FlushICache( |
| 438 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset, sizeof(Address)); | 438 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset, sizeof(Address)); |
| 439 if (host() != NULL) { | 439 if (host() != NULL) { |
| 440 Object* target_code = Code::GetCodeFromTargetAddress(target); | 440 Object* target_code = Code::GetCodeFromTargetAddress(target); |
| 441 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 441 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
| 442 host(), this, HeapObject::cast(target_code)); | 442 host(), this, HeapObject::cast(target_code)); |
| 443 } | 443 } |
| 444 } | 444 } |
| 445 | 445 |
| 446 | 446 |
| 447 Object* RelocInfo::call_object() { | 447 Object* RelocInfo::call_object() { |
| 448 return *call_object_address(); | 448 return *call_object_address(); |
| 449 } | 449 } |
| 450 | 450 |
| 451 | 451 |
| 452 void RelocInfo::set_call_object(Object* target) { | 452 void RelocInfo::set_call_object(Object* target) { |
| 453 *call_object_address() = target; | 453 *call_object_address() = target; |
| 454 } | 454 } |
| 455 | 455 |
| 456 | 456 |
| 457 Object** RelocInfo::call_object_address() { | 457 Object** RelocInfo::call_object_address() { |
| 458 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 458 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
| 459 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 459 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
| 460 return reinterpret_cast<Object**>( | 460 return reinterpret_cast<Object**>( |
| 461 pc_ + Assembler::kPatchReturnSequenceAddressOffset); | 461 pc_ + Assembler::kPatchReturnSequenceAddressOffset); |
| 462 } | 462 } |
| 463 | 463 |
| 464 | 464 |
| 465 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { | 465 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { |
| 466 RelocInfo::Mode mode = rmode(); | 466 RelocInfo::Mode mode = rmode(); |
| 467 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 467 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
| 468 visitor->VisitEmbeddedPointer(this); | 468 visitor->VisitEmbeddedPointer(this); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 } else if (RelocInfo::IsRuntimeEntry(mode)) { | 512 } else if (RelocInfo::IsRuntimeEntry(mode)) { |
| 513 StaticVisitor::VisitRuntimeEntry(this); | 513 StaticVisitor::VisitRuntimeEntry(this); |
| 514 } | 514 } |
| 515 } | 515 } |
| 516 | 516 |
| 517 | 517 |
| 518 // ----------------------------------------------------------------------------- | 518 // ----------------------------------------------------------------------------- |
| 519 // Implementation of Operand | 519 // Implementation of Operand |
| 520 | 520 |
| 521 void Operand::set_modrm(int mod, Register rm_reg) { | 521 void Operand::set_modrm(int mod, Register rm_reg) { |
| 522 ASSERT(is_uint2(mod)); | 522 DCHECK(is_uint2(mod)); |
| 523 buf_[0] = mod << 6 | rm_reg.low_bits(); | 523 buf_[0] = mod << 6 | rm_reg.low_bits(); |
| 524 // Set REX.B to the high bit of rm.code(). | 524 // Set REX.B to the high bit of rm.code(). |
| 525 rex_ |= rm_reg.high_bit(); | 525 rex_ |= rm_reg.high_bit(); |
| 526 } | 526 } |
| 527 | 527 |
| 528 | 528 |
| 529 void Operand::set_sib(ScaleFactor scale, Register index, Register base) { | 529 void Operand::set_sib(ScaleFactor scale, Register index, Register base) { |
| 530 ASSERT(len_ == 1); | 530 DCHECK(len_ == 1); |
| 531 ASSERT(is_uint2(scale)); | 531 DCHECK(is_uint2(scale)); |
| 532 // Use SIB with no index register only for base rsp or r12. Otherwise we | 532 // Use SIB with no index register only for base rsp or r12. Otherwise we |
| 533 // would skip the SIB byte entirely. | 533 // would skip the SIB byte entirely. |
| 534 ASSERT(!index.is(rsp) || base.is(rsp) || base.is(r12)); | 534 DCHECK(!index.is(rsp) || base.is(rsp) || base.is(r12)); |
| 535 buf_[1] = (scale << 6) | (index.low_bits() << 3) | base.low_bits(); | 535 buf_[1] = (scale << 6) | (index.low_bits() << 3) | base.low_bits(); |
| 536 rex_ |= index.high_bit() << 1 | base.high_bit(); | 536 rex_ |= index.high_bit() << 1 | base.high_bit(); |
| 537 len_ = 2; | 537 len_ = 2; |
| 538 } | 538 } |
| 539 | 539 |
| 540 void Operand::set_disp8(int disp) { | 540 void Operand::set_disp8(int disp) { |
| 541 ASSERT(is_int8(disp)); | 541 DCHECK(is_int8(disp)); |
| 542 ASSERT(len_ == 1 || len_ == 2); | 542 DCHECK(len_ == 1 || len_ == 2); |
| 543 int8_t* p = reinterpret_cast<int8_t*>(&buf_[len_]); | 543 int8_t* p = reinterpret_cast<int8_t*>(&buf_[len_]); |
| 544 *p = disp; | 544 *p = disp; |
| 545 len_ += sizeof(int8_t); | 545 len_ += sizeof(int8_t); |
| 546 } | 546 } |
| 547 | 547 |
| 548 void Operand::set_disp32(int disp) { | 548 void Operand::set_disp32(int disp) { |
| 549 ASSERT(len_ == 1 || len_ == 2); | 549 DCHECK(len_ == 1 || len_ == 2); |
| 550 int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); | 550 int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); |
| 551 *p = disp; | 551 *p = disp; |
| 552 len_ += sizeof(int32_t); | 552 len_ += sizeof(int32_t); |
| 553 } | 553 } |
| 554 | 554 |
| 555 | 555 |
| 556 } } // namespace v8::internal | 556 } } // namespace v8::internal |
| 557 | 557 |
| 558 #endif // V8_X64_ASSEMBLER_X64_INL_H_ | 558 #endif // V8_X64_ASSEMBLER_X64_INL_H_ |
| OLD | NEW |