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 | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 DCHECK(index >= 0 && index < NumAllocatableRegisters()); | 90 DCHECK(index >= 0 && index < NumAllocatableRegisters()); |
91 DCHECK(kScratchDoubleReg.code() - kDoubleRegZero.code() == | 91 DCHECK(kScratchDoubleReg.code() - kDoubleRegZero.code() == |
92 kNumReservedRegisters - 1); | 92 kNumReservedRegisters - 1); |
93 if (index >= kDoubleRegZero.code()) { | 93 if (index >= kDoubleRegZero.code()) { |
94 return from_code(index + kNumReservedRegisters); | 94 return from_code(index + kNumReservedRegisters); |
95 } | 95 } |
96 return from_code(index); | 96 return from_code(index); |
97 } | 97 } |
98 | 98 |
99 | 99 |
100 void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) { | 100 void RelocInfo::apply(intptr_t delta) { |
101 if (RelocInfo::IsInternalReference(rmode_)) { | 101 if (RelocInfo::IsInternalReference(rmode_)) { |
102 // absolute code pointer inside code object moves with the code object. | 102 // absolute code pointer inside code object moves with the code object. |
103 int32_t* p = reinterpret_cast<int32_t*>(pc_); | 103 int32_t* p = reinterpret_cast<int32_t*>(pc_); |
104 *p += delta; // relocate entry | 104 *p += delta; // relocate entry |
105 } | 105 } |
106 // We do not use pc relative addressing on ARM, so there is | 106 // We do not use pc relative addressing on ARM, so there is |
107 // nothing else to do. | 107 // nothing else to do. |
108 } | 108 } |
109 | 109 |
110 | 110 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 | 265 |
266 void RelocInfo::set_code_age_stub(Code* stub, | 266 void RelocInfo::set_code_age_stub(Code* stub, |
267 ICacheFlushMode icache_flush_mode) { | 267 ICacheFlushMode icache_flush_mode) { |
268 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 268 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
269 Memory::Address_at(pc_ + | 269 Memory::Address_at(pc_ + |
270 (kNoCodeAgeSequenceLength - Assembler::kInstrSize)) = | 270 (kNoCodeAgeSequenceLength - Assembler::kInstrSize)) = |
271 stub->instruction_start(); | 271 stub->instruction_start(); |
272 } | 272 } |
273 | 273 |
274 | 274 |
275 Address RelocInfo::call_address() { | 275 Address RelocInfo::debug_call_address() { |
276 // The 2 instructions offset assumes patched debug break slot or return | 276 // The 2 instructions offset assumes patched debug break slot or return |
277 // sequence. | 277 // sequence. |
278 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 278 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); |
279 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 279 return Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset); |
280 return Memory::Address_at(pc_ + 2 * Assembler::kInstrSize); | |
281 } | 280 } |
282 | 281 |
283 | 282 |
284 void RelocInfo::set_call_address(Address target) { | 283 void RelocInfo::set_debug_call_address(Address target) { |
285 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 284 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); |
286 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 285 Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset) = |
287 Memory::Address_at(pc_ + 2 * Assembler::kInstrSize) = target; | 286 target; |
288 if (host() != NULL) { | 287 if (host() != NULL) { |
289 Object* target_code = Code::GetCodeFromTargetAddress(target); | 288 Object* target_code = Code::GetCodeFromTargetAddress(target); |
290 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 289 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
291 host(), this, HeapObject::cast(target_code)); | 290 host(), this, HeapObject::cast(target_code)); |
292 } | 291 } |
293 } | 292 } |
294 | 293 |
295 | 294 |
296 Object* RelocInfo::call_object() { | |
297 return *call_object_address(); | |
298 } | |
299 | |
300 | |
301 void RelocInfo::set_call_object(Object* target) { | |
302 *call_object_address() = target; | |
303 } | |
304 | |
305 | |
306 Object** RelocInfo::call_object_address() { | |
307 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | |
308 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | |
309 return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize); | |
310 } | |
311 | |
312 | |
313 void RelocInfo::WipeOut() { | 295 void RelocInfo::WipeOut() { |
314 DCHECK(IsEmbeddedObject(rmode_) || IsCodeTarget(rmode_) || | 296 DCHECK(IsEmbeddedObject(rmode_) || IsCodeTarget(rmode_) || |
315 IsRuntimeEntry(rmode_) || IsExternalReference(rmode_) || | 297 IsRuntimeEntry(rmode_) || IsExternalReference(rmode_) || |
316 IsInternalReference(rmode_)); | 298 IsInternalReference(rmode_)); |
317 if (IsInternalReference(rmode_)) { | 299 if (IsInternalReference(rmode_)) { |
318 Memory::Address_at(pc_) = NULL; | 300 Memory::Address_at(pc_) = NULL; |
319 } else { | 301 } else { |
320 Assembler::set_target_address_at(pc_, host_, NULL); | 302 Assembler::set_target_address_at(pc_, host_, NULL); |
321 } | 303 } |
322 } | 304 } |
(...skipping 23 matching lines...) Expand all Loading... |
346 } else if (RelocInfo::IsCodeTarget(mode)) { | 328 } else if (RelocInfo::IsCodeTarget(mode)) { |
347 visitor->VisitCodeTarget(this); | 329 visitor->VisitCodeTarget(this); |
348 } else if (mode == RelocInfo::CELL) { | 330 } else if (mode == RelocInfo::CELL) { |
349 visitor->VisitCell(this); | 331 visitor->VisitCell(this); |
350 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 332 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
351 visitor->VisitExternalReference(this); | 333 visitor->VisitExternalReference(this); |
352 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { | 334 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { |
353 visitor->VisitInternalReference(this); | 335 visitor->VisitInternalReference(this); |
354 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 336 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
355 visitor->VisitCodeAgeSequence(this); | 337 visitor->VisitCodeAgeSequence(this); |
356 } else if (((RelocInfo::IsJSReturn(mode) && | 338 } else if (RelocInfo::IsDebugBreakSlot(mode) && |
357 IsPatchedReturnSequence()) || | 339 IsPatchedDebugBreakSlotSequence() && |
358 (RelocInfo::IsDebugBreakSlot(mode) && | |
359 IsPatchedDebugBreakSlotSequence())) && | |
360 isolate->debug()->has_break_points()) { | 340 isolate->debug()->has_break_points()) { |
361 visitor->VisitDebugTarget(this); | 341 visitor->VisitDebugTarget(this); |
362 } else if (RelocInfo::IsRuntimeEntry(mode)) { | 342 } else if (RelocInfo::IsRuntimeEntry(mode)) { |
363 visitor->VisitRuntimeEntry(this); | 343 visitor->VisitRuntimeEntry(this); |
364 } | 344 } |
365 } | 345 } |
366 | 346 |
367 | 347 |
368 template<typename StaticVisitor> | 348 template<typename StaticVisitor> |
369 void RelocInfo::Visit(Heap* heap) { | 349 void RelocInfo::Visit(Heap* heap) { |
370 RelocInfo::Mode mode = rmode(); | 350 RelocInfo::Mode mode = rmode(); |
371 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 351 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
372 StaticVisitor::VisitEmbeddedPointer(heap, this); | 352 StaticVisitor::VisitEmbeddedPointer(heap, this); |
373 } else if (RelocInfo::IsCodeTarget(mode)) { | 353 } else if (RelocInfo::IsCodeTarget(mode)) { |
374 StaticVisitor::VisitCodeTarget(heap, this); | 354 StaticVisitor::VisitCodeTarget(heap, this); |
375 } else if (mode == RelocInfo::CELL) { | 355 } else if (mode == RelocInfo::CELL) { |
376 StaticVisitor::VisitCell(heap, this); | 356 StaticVisitor::VisitCell(heap, this); |
377 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 357 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
378 StaticVisitor::VisitExternalReference(this); | 358 StaticVisitor::VisitExternalReference(this); |
379 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { | 359 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { |
380 StaticVisitor::VisitInternalReference(this); | 360 StaticVisitor::VisitInternalReference(this); |
381 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 361 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
382 StaticVisitor::VisitCodeAgeSequence(heap, this); | 362 StaticVisitor::VisitCodeAgeSequence(heap, this); |
383 } else if (heap->isolate()->debug()->has_break_points() && | 363 } else if (heap->isolate()->debug()->has_break_points() && |
384 ((RelocInfo::IsJSReturn(mode) && | 364 RelocInfo::IsDebugBreakSlot(mode) && |
385 IsPatchedReturnSequence()) || | 365 IsPatchedDebugBreakSlotSequence()) { |
386 (RelocInfo::IsDebugBreakSlot(mode) && | |
387 IsPatchedDebugBreakSlotSequence()))) { | |
388 StaticVisitor::VisitDebugTarget(heap, this); | 366 StaticVisitor::VisitDebugTarget(heap, this); |
389 } else if (RelocInfo::IsRuntimeEntry(mode)) { | 367 } else if (RelocInfo::IsRuntimeEntry(mode)) { |
390 StaticVisitor::VisitRuntimeEntry(this); | 368 StaticVisitor::VisitRuntimeEntry(this); |
391 } | 369 } |
392 } | 370 } |
393 | 371 |
394 | 372 |
395 Operand::Operand(int32_t immediate, RelocInfo::Mode rmode) { | 373 Operand::Operand(int32_t immediate, RelocInfo::Mode rmode) { |
396 rm_ = no_reg; | 374 rm_ = no_reg; |
397 imm32_ = immediate; | 375 imm32_ = immediate; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 IsMovImmed(Memory::int32_at(candidate)) && | 475 IsMovImmed(Memory::int32_at(candidate)) && |
498 IsOrrImmed(Memory::int32_at(candidate + Assembler::kInstrSize)) && | 476 IsOrrImmed(Memory::int32_at(candidate + Assembler::kInstrSize)) && |
499 IsOrrImmed(Memory::int32_at(candidate + 2 * Assembler::kInstrSize)) && | 477 IsOrrImmed(Memory::int32_at(candidate + 2 * Assembler::kInstrSize)) && |
500 IsOrrImmed(Memory::int32_at(candidate + 3 * Assembler::kInstrSize))); | 478 IsOrrImmed(Memory::int32_at(candidate + 3 * Assembler::kInstrSize))); |
501 } | 479 } |
502 return candidate; | 480 return candidate; |
503 } | 481 } |
504 } | 482 } |
505 | 483 |
506 | 484 |
507 Address Assembler::break_address_from_return_address(Address pc) { | |
508 return pc - Assembler::kPatchDebugBreakSlotReturnOffset; | |
509 } | |
510 | |
511 | |
512 Address Assembler::return_address_from_call_start(Address pc) { | 485 Address Assembler::return_address_from_call_start(Address pc) { |
513 if (IsLdrPcImmediateOffset(Memory::int32_at(pc)) | | 486 if (IsLdrPcImmediateOffset(Memory::int32_at(pc)) | |
514 IsLdrPpImmediateOffset(Memory::int32_at(pc))) { | 487 IsLdrPpImmediateOffset(Memory::int32_at(pc))) { |
515 // Load from constant pool, small section. | 488 // Load from constant pool, small section. |
516 return pc + kInstrSize * 2; | 489 return pc + kInstrSize * 2; |
517 } else { | 490 } else { |
518 if (CpuFeatures::IsSupported(ARMv7)) { | 491 if (CpuFeatures::IsSupported(ARMv7)) { |
519 DCHECK(IsMovW(Memory::int32_at(pc))); | 492 DCHECK(IsMovW(Memory::int32_at(pc))); |
520 DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize))); | 493 DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize))); |
521 if (IsLdrPpRegOffset(Memory::int32_at(pc + 2 * kInstrSize))) { | 494 if (IsLdrPpRegOffset(Memory::int32_at(pc + 2 * kInstrSize))) { |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 664 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
692 CpuFeatures::FlushICache(pc, 4 * kInstrSize); | 665 CpuFeatures::FlushICache(pc, 4 * kInstrSize); |
693 } | 666 } |
694 } | 667 } |
695 } | 668 } |
696 | 669 |
697 | 670 |
698 } } // namespace v8::internal | 671 } } // namespace v8::internal |
699 | 672 |
700 #endif // V8_ARM_ASSEMBLER_ARM_INL_H_ | 673 #endif // V8_ARM_ASSEMBLER_ARM_INL_H_ |
OLD | NEW |