Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Side by Side Diff: src/ia32/assembler-ia32-inl.h

Issue 1234833003: Debugger: use debug break slots to break at function exit. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase, clean ups, x64 port. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « src/ia32/assembler-ia32.cc ('k') | src/ia32/debug-ia32.cc » ('j') | src/liveedit.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698