| 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 namespace internal { | 46 namespace internal { |
| 47 | 47 |
| 48 bool CpuFeatures::SupportsCrankshaft() { return true; } | 48 bool CpuFeatures::SupportsCrankshaft() { return true; } |
| 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) { |
| 57 bool flush_icache = icache_flush_mode != SKIP_ICACHE_FLUSH; | |
| 58 if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_)) { | 57 if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_)) { |
| 59 int32_t* p = reinterpret_cast<int32_t*>(pc_); | 58 int32_t* p = reinterpret_cast<int32_t*>(pc_); |
| 60 *p -= delta; // Relocate entry. | 59 *p -= delta; // Relocate entry. |
| 61 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); | |
| 62 } else if (IsCodeAgeSequence(rmode_)) { | 60 } else if (IsCodeAgeSequence(rmode_)) { |
| 63 if (*pc_ == kCallOpcode) { | 61 if (*pc_ == kCallOpcode) { |
| 64 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | 62 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); |
| 65 *p -= delta; // Relocate entry. | 63 *p -= delta; // Relocate entry. |
| 66 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); | |
| 67 } | 64 } |
| 68 } else if (IsJSReturn(rmode_) && IsPatchedReturnSequence()) { | |
| 69 // Special handling of js_return when a break point is set (call | |
| 70 // instruction has been inserted). | |
| 71 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | |
| 72 *p -= delta; // Relocate entry. | |
| 73 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); | |
| 74 } else if (IsDebugBreakSlot(rmode_) && IsPatchedDebugBreakSlotSequence()) { | 65 } else if (IsDebugBreakSlot(rmode_) && IsPatchedDebugBreakSlotSequence()) { |
| 75 // Special handling of a debug break slot when a break point is set (call | 66 // Special handling of a debug break slot when a break point is set (call |
| 76 // instruction has been inserted). | 67 // instruction has been inserted). |
| 77 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | 68 int32_t* p = reinterpret_cast<int32_t*>( |
| 69 pc_ + Assembler::kPatchDebugBreakSlotAddressOffset); |
| 78 *p -= delta; // Relocate entry. | 70 *p -= delta; // Relocate entry. |
| 79 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); | |
| 80 } else if (IsInternalReference(rmode_)) { | 71 } else if (IsInternalReference(rmode_)) { |
| 81 // absolute code pointer inside code object moves with the code object. | 72 // absolute code pointer inside code object moves with the code object. |
| 82 int32_t* p = reinterpret_cast<int32_t*>(pc_); | 73 int32_t* p = reinterpret_cast<int32_t*>(pc_); |
| 83 *p += delta; // Relocate entry. | 74 *p += delta; // Relocate entry. |
| 84 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); | |
| 85 } | 75 } |
| 86 } | 76 } |
| 87 | 77 |
| 88 | 78 |
| 89 Address RelocInfo::target_address() { | 79 Address RelocInfo::target_address() { |
| 90 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 80 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
| 91 return Assembler::target_address_at(pc_, host_); | 81 return Assembler::target_address_at(pc_, host_); |
| 92 } | 82 } |
| 93 | 83 |
| 94 | 84 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 | 227 |
| 238 void RelocInfo::set_code_age_stub(Code* stub, | 228 void RelocInfo::set_code_age_stub(Code* stub, |
| 239 ICacheFlushMode icache_flush_mode) { | 229 ICacheFlushMode icache_flush_mode) { |
| 240 DCHECK(*pc_ == kCallOpcode); | 230 DCHECK(*pc_ == kCallOpcode); |
| 241 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 231 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
| 242 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), | 232 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), |
| 243 icache_flush_mode); | 233 icache_flush_mode); |
| 244 } | 234 } |
| 245 | 235 |
| 246 | 236 |
| 247 Address RelocInfo::call_address() { | 237 Address RelocInfo::debug_call_address() { |
| 248 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 238 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); |
| 249 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 239 Address location = pc_ + Assembler::kPatchDebugBreakSlotAddressOffset; |
| 250 return Assembler::target_address_at(pc_ + 1, host_); | 240 return Assembler::target_address_at(location, host_); |
| 251 } | 241 } |
| 252 | 242 |
| 253 | 243 |
| 254 void RelocInfo::set_call_address(Address target) { | 244 void RelocInfo::set_debug_call_address(Address target) { |
| 255 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 245 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); |
| 256 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 246 Address location = pc_ + Assembler::kPatchDebugBreakSlotAddressOffset; |
| 257 Assembler::set_target_address_at(pc_ + 1, host_, target); | 247 Assembler::set_target_address_at(location, host_, target); |
| 258 if (host() != NULL) { | 248 if (host() != NULL) { |
| 259 Object* target_code = Code::GetCodeFromTargetAddress(target); | 249 Object* target_code = Code::GetCodeFromTargetAddress(target); |
| 260 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 250 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
| 261 host(), this, HeapObject::cast(target_code)); | 251 host(), this, HeapObject::cast(target_code)); |
| 262 } | 252 } |
| 263 } | 253 } |
| 264 | 254 |
| 265 | 255 |
| 266 Object* RelocInfo::call_object() { | |
| 267 return *call_object_address(); | |
| 268 } | |
| 269 | |
| 270 | |
| 271 void RelocInfo::set_call_object(Object* target) { | |
| 272 *call_object_address() = target; | |
| 273 } | |
| 274 | |
| 275 | |
| 276 Object** RelocInfo::call_object_address() { | |
| 277 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | |
| 278 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | |
| 279 return reinterpret_cast<Object**>(pc_ + 1); | |
| 280 } | |
| 281 | |
| 282 | |
| 283 void RelocInfo::WipeOut() { | 256 void RelocInfo::WipeOut() { |
| 284 if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) || | 257 if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) || |
| 285 IsInternalReference(rmode_)) { | 258 IsInternalReference(rmode_)) { |
| 286 Memory::Address_at(pc_) = NULL; | 259 Memory::Address_at(pc_) = NULL; |
| 287 } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { | 260 } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { |
| 288 // Effectively write zero into the relocation. | 261 // Effectively write zero into the relocation. |
| 289 Assembler::set_target_address_at(pc_, host_, pc_ + sizeof(int32_t)); | 262 Assembler::set_target_address_at(pc_, host_, pc_ + sizeof(int32_t)); |
| 290 } else { | 263 } else { |
| 291 UNREACHABLE(); | 264 UNREACHABLE(); |
| 292 } | 265 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 311 } else if (RelocInfo::IsCodeTarget(mode)) { | 284 } else if (RelocInfo::IsCodeTarget(mode)) { |
| 312 visitor->VisitCodeTarget(this); | 285 visitor->VisitCodeTarget(this); |
| 313 } else if (mode == RelocInfo::CELL) { | 286 } else if (mode == RelocInfo::CELL) { |
| 314 visitor->VisitCell(this); | 287 visitor->VisitCell(this); |
| 315 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 288 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
| 316 visitor->VisitExternalReference(this); | 289 visitor->VisitExternalReference(this); |
| 317 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { | 290 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { |
| 318 visitor->VisitInternalReference(this); | 291 visitor->VisitInternalReference(this); |
| 319 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 292 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
| 320 visitor->VisitCodeAgeSequence(this); | 293 visitor->VisitCodeAgeSequence(this); |
| 321 } else if (((RelocInfo::IsJSReturn(mode) && | 294 } else if (RelocInfo::IsDebugBreakSlot(mode) && |
| 322 IsPatchedReturnSequence()) || | 295 IsPatchedDebugBreakSlotSequence() && |
| 323 (RelocInfo::IsDebugBreakSlot(mode) && | |
| 324 IsPatchedDebugBreakSlotSequence())) && | |
| 325 isolate->debug()->has_break_points()) { | 296 isolate->debug()->has_break_points()) { |
| 326 visitor->VisitDebugTarget(this); | 297 visitor->VisitDebugTarget(this); |
| 327 } else if (IsRuntimeEntry(mode)) { | 298 } else if (IsRuntimeEntry(mode)) { |
| 328 visitor->VisitRuntimeEntry(this); | 299 visitor->VisitRuntimeEntry(this); |
| 329 } | 300 } |
| 330 } | 301 } |
| 331 | 302 |
| 332 | 303 |
| 333 template<typename StaticVisitor> | 304 template<typename StaticVisitor> |
| 334 void RelocInfo::Visit(Heap* heap) { | 305 void RelocInfo::Visit(Heap* heap) { |
| 335 RelocInfo::Mode mode = rmode(); | 306 RelocInfo::Mode mode = rmode(); |
| 336 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 307 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
| 337 StaticVisitor::VisitEmbeddedPointer(heap, this); | 308 StaticVisitor::VisitEmbeddedPointer(heap, this); |
| 338 CpuFeatures::FlushICache(pc_, sizeof(Address)); | 309 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
| 339 } else if (RelocInfo::IsCodeTarget(mode)) { | 310 } else if (RelocInfo::IsCodeTarget(mode)) { |
| 340 StaticVisitor::VisitCodeTarget(heap, this); | 311 StaticVisitor::VisitCodeTarget(heap, this); |
| 341 } else if (mode == RelocInfo::CELL) { | 312 } else if (mode == RelocInfo::CELL) { |
| 342 StaticVisitor::VisitCell(heap, this); | 313 StaticVisitor::VisitCell(heap, this); |
| 343 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 314 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
| 344 StaticVisitor::VisitExternalReference(this); | 315 StaticVisitor::VisitExternalReference(this); |
| 345 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { | 316 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { |
| 346 StaticVisitor::VisitInternalReference(this); | 317 StaticVisitor::VisitInternalReference(this); |
| 347 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 318 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
| 348 StaticVisitor::VisitCodeAgeSequence(heap, this); | 319 StaticVisitor::VisitCodeAgeSequence(heap, this); |
| 349 } else if (heap->isolate()->debug()->has_break_points() && | 320 } else if (heap->isolate()->debug()->has_break_points() && |
| 350 ((RelocInfo::IsJSReturn(mode) && | 321 RelocInfo::IsDebugBreakSlot(mode) && |
| 351 IsPatchedReturnSequence()) || | 322 IsPatchedDebugBreakSlotSequence()) { |
| 352 (RelocInfo::IsDebugBreakSlot(mode) && | |
| 353 IsPatchedDebugBreakSlotSequence()))) { | |
| 354 StaticVisitor::VisitDebugTarget(heap, this); | 323 StaticVisitor::VisitDebugTarget(heap, this); |
| 355 } else if (IsRuntimeEntry(mode)) { | 324 } else if (IsRuntimeEntry(mode)) { |
| 356 StaticVisitor::VisitRuntimeEntry(this); | 325 StaticVisitor::VisitRuntimeEntry(this); |
| 357 } | 326 } |
| 358 } | 327 } |
| 359 | 328 |
| 360 | 329 |
| 361 | 330 |
| 362 Immediate::Immediate(int x) { | 331 Immediate::Immediate(int x) { |
| 363 x_ = x; | 332 x_ = x; |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 CpuFeatures::FlushICache(p, sizeof(int32_t)); | 464 CpuFeatures::FlushICache(p, sizeof(int32_t)); |
| 496 } | 465 } |
| 497 } | 466 } |
| 498 | 467 |
| 499 | 468 |
| 500 Address Assembler::target_address_from_return_address(Address pc) { | 469 Address Assembler::target_address_from_return_address(Address pc) { |
| 501 return pc - kCallTargetAddressOffset; | 470 return pc - kCallTargetAddressOffset; |
| 502 } | 471 } |
| 503 | 472 |
| 504 | 473 |
| 505 Address Assembler::break_address_from_return_address(Address pc) { | |
| 506 return pc - Assembler::kPatchDebugBreakSlotReturnOffset; | |
| 507 } | |
| 508 | |
| 509 | |
| 510 Displacement Assembler::disp_at(Label* L) { | 474 Displacement Assembler::disp_at(Label* L) { |
| 511 return Displacement(long_at(L->pos())); | 475 return Displacement(long_at(L->pos())); |
| 512 } | 476 } |
| 513 | 477 |
| 514 | 478 |
| 515 void Assembler::disp_at_put(Label* L, Displacement disp) { | 479 void Assembler::disp_at_put(Label* L, Displacement disp) { |
| 516 long_at_put(L->pos(), disp.data()); | 480 long_at_put(L->pos(), disp.data()); |
| 517 } | 481 } |
| 518 | 482 |
| 519 | 483 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 | 557 |
| 594 | 558 |
| 595 Operand::Operand(Immediate imm) { | 559 Operand::Operand(Immediate imm) { |
| 596 // [disp/r] | 560 // [disp/r] |
| 597 set_modrm(0, ebp); | 561 set_modrm(0, ebp); |
| 598 set_dispr(imm.x_, imm.rmode_); | 562 set_dispr(imm.x_, imm.rmode_); |
| 599 } | 563 } |
| 600 } } // namespace v8::internal | 564 } } // namespace v8::internal |
| 601 | 565 |
| 602 #endif // V8_IA32_ASSEMBLER_IA32_INL_H_ | 566 #endif // V8_IA32_ASSEMBLER_IA32_INL_H_ |
| OLD | NEW |