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