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

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

Issue 284153004: Avoid flushing the icache unnecessarily when updating target addresses in code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix intenting Created 6 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « src/ia32/assembler-ia32.h ('k') | src/objects.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
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) { 56 void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) {
57 bool flush_icache = icache_flush_mode != SKIP_ICACHE_FLUSH;
57 if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_)) { 58 if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_)) {
58 int32_t* p = reinterpret_cast<int32_t*>(pc_); 59 int32_t* p = reinterpret_cast<int32_t*>(pc_);
59 *p -= delta; // Relocate entry. 60 *p -= delta; // Relocate entry.
60 CPU::FlushICache(p, sizeof(uint32_t)); 61 if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t));
61 } else if (rmode_ == CODE_AGE_SEQUENCE) { 62 } else if (rmode_ == CODE_AGE_SEQUENCE) {
62 if (*pc_ == kCallOpcode) { 63 if (*pc_ == kCallOpcode) {
63 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); 64 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
64 *p -= delta; // Relocate entry. 65 *p -= delta; // Relocate entry.
65 CPU::FlushICache(p, sizeof(uint32_t)); 66 if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t));
66 } 67 }
67 } else if (rmode_ == JS_RETURN && IsPatchedReturnSequence()) { 68 } else if (rmode_ == JS_RETURN && IsPatchedReturnSequence()) {
68 // Special handling of js_return when a break point is set (call 69 // Special handling of js_return when a break point is set (call
69 // instruction has been inserted). 70 // instruction has been inserted).
70 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); 71 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
71 *p -= delta; // Relocate entry. 72 *p -= delta; // Relocate entry.
72 CPU::FlushICache(p, sizeof(uint32_t)); 73 if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t));
73 } else if (rmode_ == DEBUG_BREAK_SLOT && IsPatchedDebugBreakSlotSequence()) { 74 } else if (rmode_ == DEBUG_BREAK_SLOT && IsPatchedDebugBreakSlotSequence()) {
74 // Special handling of a debug break slot when a break point is set (call 75 // Special handling of a debug break slot when a break point is set (call
75 // instruction has been inserted). 76 // instruction has been inserted).
76 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); 77 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
77 *p -= delta; // Relocate entry. 78 *p -= delta; // Relocate entry.
78 CPU::FlushICache(p, sizeof(uint32_t)); 79 if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t));
79 } else if (IsInternalReference(rmode_)) { 80 } else if (IsInternalReference(rmode_)) {
80 // absolute code pointer inside code object moves with the code object. 81 // absolute code pointer inside code object moves with the code object.
81 int32_t* p = reinterpret_cast<int32_t*>(pc_); 82 int32_t* p = reinterpret_cast<int32_t*>(pc_);
82 *p += delta; // Relocate entry. 83 *p += delta; // Relocate entry.
83 CPU::FlushICache(p, sizeof(uint32_t)); 84 if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t));
84 } 85 }
85 } 86 }
86 87
87 88
88 Address RelocInfo::target_address() { 89 Address RelocInfo::target_address() {
89 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); 90 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
90 return Assembler::target_address_at(pc_, host_); 91 return Assembler::target_address_at(pc_, host_);
91 } 92 }
92 93
93 94
94 Address RelocInfo::target_address_address() { 95 Address RelocInfo::target_address_address() {
95 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) 96 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
96 || rmode_ == EMBEDDED_OBJECT 97 || rmode_ == EMBEDDED_OBJECT
97 || rmode_ == EXTERNAL_REFERENCE); 98 || rmode_ == EXTERNAL_REFERENCE);
98 return reinterpret_cast<Address>(pc_); 99 return reinterpret_cast<Address>(pc_);
99 } 100 }
100 101
101 102
102 Address RelocInfo::constant_pool_entry_address() { 103 Address RelocInfo::constant_pool_entry_address() {
103 UNREACHABLE(); 104 UNREACHABLE();
104 return NULL; 105 return NULL;
105 } 106 }
106 107
107 108
108 int RelocInfo::target_address_size() { 109 int RelocInfo::target_address_size() {
109 return Assembler::kSpecialTargetSize; 110 return Assembler::kSpecialTargetSize;
110 } 111 }
111 112
112 113
113 void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) { 114 void RelocInfo::set_target_address(Address target,
114 Assembler::set_target_address_at(pc_, host_, target); 115 WriteBarrierMode write_barrier_mode,
116 ICacheFlushMode icache_flush_mode) {
117 Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode);
115 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); 118 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
116 if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) { 119 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL &&
120 IsCodeTarget(rmode_)) {
117 Object* target_code = Code::GetCodeFromTargetAddress(target); 121 Object* target_code = Code::GetCodeFromTargetAddress(target);
118 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( 122 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
119 host(), this, HeapObject::cast(target_code)); 123 host(), this, HeapObject::cast(target_code));
120 } 124 }
121 } 125 }
122 126
123 127
124 Object* RelocInfo::target_object() { 128 Object* RelocInfo::target_object() {
125 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 129 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
126 return Memory::Object_at(pc_); 130 return Memory::Object_at(pc_);
127 } 131 }
128 132
129 133
130 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { 134 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) {
131 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 135 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
132 return Memory::Object_Handle_at(pc_); 136 return Memory::Object_Handle_at(pc_);
133 } 137 }
134 138
135 139
136 void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) { 140 void RelocInfo::set_target_object(Object* target,
141 WriteBarrierMode write_barrier_mode,
142 ICacheFlushMode icache_flush_mode) {
137 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 143 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
138 ASSERT(!target->IsConsString()); 144 ASSERT(!target->IsConsString());
139 Memory::Object_at(pc_) = target; 145 Memory::Object_at(pc_) = target;
140 CPU::FlushICache(pc_, sizeof(Address)); 146 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
141 if (mode == UPDATE_WRITE_BARRIER && 147 CPU::FlushICache(pc_, sizeof(Address));
148 }
149 if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
142 host() != NULL && 150 host() != NULL &&
143 target->IsHeapObject()) { 151 target->IsHeapObject()) {
144 host()->GetHeap()->incremental_marking()->RecordWrite( 152 host()->GetHeap()->incremental_marking()->RecordWrite(
145 host(), &Memory::Object_at(pc_), HeapObject::cast(target)); 153 host(), &Memory::Object_at(pc_), HeapObject::cast(target));
146 } 154 }
147 } 155 }
148 156
149 157
150 Address RelocInfo::target_reference() { 158 Address RelocInfo::target_reference() {
151 ASSERT(rmode_ == RelocInfo::EXTERNAL_REFERENCE); 159 ASSERT(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
152 return Memory::Address_at(pc_); 160 return Memory::Address_at(pc_);
153 } 161 }
154 162
155 163
156 Address RelocInfo::target_runtime_entry(Assembler* origin) { 164 Address RelocInfo::target_runtime_entry(Assembler* origin) {
157 ASSERT(IsRuntimeEntry(rmode_)); 165 ASSERT(IsRuntimeEntry(rmode_));
158 return reinterpret_cast<Address>(*reinterpret_cast<int32_t*>(pc_)); 166 return reinterpret_cast<Address>(*reinterpret_cast<int32_t*>(pc_));
159 } 167 }
160 168
161 169
162 void RelocInfo::set_target_runtime_entry(Address target, 170 void RelocInfo::set_target_runtime_entry(Address target,
163 WriteBarrierMode mode) { 171 WriteBarrierMode write_barrier_mode,
172 ICacheFlushMode icache_flush_mode) {
164 ASSERT(IsRuntimeEntry(rmode_)); 173 ASSERT(IsRuntimeEntry(rmode_));
165 if (target_address() != target) set_target_address(target, mode); 174 if (target_address() != target) {
175 set_target_address(target, write_barrier_mode, icache_flush_mode);
176 }
166 } 177 }
167 178
168 179
169 Handle<Cell> RelocInfo::target_cell_handle() { 180 Handle<Cell> RelocInfo::target_cell_handle() {
170 ASSERT(rmode_ == RelocInfo::CELL); 181 ASSERT(rmode_ == RelocInfo::CELL);
171 Address address = Memory::Address_at(pc_); 182 Address address = Memory::Address_at(pc_);
172 return Handle<Cell>(reinterpret_cast<Cell**>(address)); 183 return Handle<Cell>(reinterpret_cast<Cell**>(address));
173 } 184 }
174 185
175 186
176 Cell* RelocInfo::target_cell() { 187 Cell* RelocInfo::target_cell() {
177 ASSERT(rmode_ == RelocInfo::CELL); 188 ASSERT(rmode_ == RelocInfo::CELL);
178 return Cell::FromValueAddress(Memory::Address_at(pc_)); 189 return Cell::FromValueAddress(Memory::Address_at(pc_));
179 } 190 }
180 191
181 192
182 void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode mode) { 193 void RelocInfo::set_target_cell(Cell* cell,
194 WriteBarrierMode write_barrier_mode,
195 ICacheFlushMode icache_flush_mode) {
183 ASSERT(rmode_ == RelocInfo::CELL); 196 ASSERT(rmode_ == RelocInfo::CELL);
184 Address address = cell->address() + Cell::kValueOffset; 197 Address address = cell->address() + Cell::kValueOffset;
185 Memory::Address_at(pc_) = address; 198 Memory::Address_at(pc_) = address;
186 CPU::FlushICache(pc_, sizeof(Address)); 199 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
187 if (mode == UPDATE_WRITE_BARRIER && host() != NULL) { 200 CPU::FlushICache(pc_, sizeof(Address));
201 }
202 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) {
188 // TODO(1550) We are passing NULL as a slot because cell can never be on 203 // TODO(1550) We are passing NULL as a slot because cell can never be on
189 // evacuation candidate. 204 // evacuation candidate.
190 host()->GetHeap()->incremental_marking()->RecordWrite( 205 host()->GetHeap()->incremental_marking()->RecordWrite(
191 host(), NULL, cell); 206 host(), NULL, cell);
192 } 207 }
193 } 208 }
194 209
195 210
196 Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { 211 Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) {
197 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 212 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
198 ASSERT(*pc_ == kCallOpcode); 213 ASSERT(*pc_ == kCallOpcode);
199 return Memory::Object_Handle_at(pc_ + 1); 214 return Memory::Object_Handle_at(pc_ + 1);
200 } 215 }
201 216
202 217
203 Code* RelocInfo::code_age_stub() { 218 Code* RelocInfo::code_age_stub() {
204 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 219 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
205 ASSERT(*pc_ == kCallOpcode); 220 ASSERT(*pc_ == kCallOpcode);
206 return Code::GetCodeFromTargetAddress( 221 return Code::GetCodeFromTargetAddress(
207 Assembler::target_address_at(pc_ + 1, host_)); 222 Assembler::target_address_at(pc_ + 1, host_));
208 } 223 }
209 224
210 225
211 void RelocInfo::set_code_age_stub(Code* stub) { 226 void RelocInfo::set_code_age_stub(Code* stub,
227 ICacheFlushMode icache_flush_mode) {
212 ASSERT(*pc_ == kCallOpcode); 228 ASSERT(*pc_ == kCallOpcode);
213 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 229 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
214 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start()); 230 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(),
231 icache_flush_mode);
215 } 232 }
216 233
217 234
218 Address RelocInfo::call_address() { 235 Address RelocInfo::call_address() {
219 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 236 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
220 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); 237 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
221 return Assembler::target_address_at(pc_ + 1, host_); 238 return Assembler::target_address_at(pc_ + 1, host_);
222 } 239 }
223 240
224 241
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 461
445 462
446 Address Assembler::target_address_at(Address pc, 463 Address Assembler::target_address_at(Address pc,
447 ConstantPoolArray* constant_pool) { 464 ConstantPoolArray* constant_pool) {
448 return pc + sizeof(int32_t) + *reinterpret_cast<int32_t*>(pc); 465 return pc + sizeof(int32_t) + *reinterpret_cast<int32_t*>(pc);
449 } 466 }
450 467
451 468
452 void Assembler::set_target_address_at(Address pc, 469 void Assembler::set_target_address_at(Address pc,
453 ConstantPoolArray* constant_pool, 470 ConstantPoolArray* constant_pool,
454 Address target) { 471 Address target,
472 ICacheFlushMode icache_flush_mode) {
455 int32_t* p = reinterpret_cast<int32_t*>(pc); 473 int32_t* p = reinterpret_cast<int32_t*>(pc);
456 *p = target - (pc + sizeof(int32_t)); 474 *p = target - (pc + sizeof(int32_t));
457 CPU::FlushICache(p, sizeof(int32_t)); 475 if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
476 CPU::FlushICache(p, sizeof(int32_t));
477 }
458 } 478 }
459 479
460 480
461 Address Assembler::target_address_from_return_address(Address pc) { 481 Address Assembler::target_address_from_return_address(Address pc) {
462 return pc - kCallTargetAddressOffset; 482 return pc - kCallTargetAddressOffset;
463 } 483 }
464 484
465 485
466 Displacement Assembler::disp_at(Label* L) { 486 Displacement Assembler::disp_at(Label* L) {
467 return Displacement(long_at(L->pos())); 487 return Displacement(long_at(L->pos()));
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 557
538 Operand::Operand(int32_t disp, RelocInfo::Mode rmode) { 558 Operand::Operand(int32_t disp, RelocInfo::Mode rmode) {
539 // [disp/r] 559 // [disp/r]
540 set_modrm(0, ebp); 560 set_modrm(0, ebp);
541 set_dispr(disp, rmode); 561 set_dispr(disp, rmode);
542 } 562 }
543 563
544 } } // namespace v8::internal 564 } } // namespace v8::internal
545 565
546 #endif // V8_IA32_ASSEMBLER_IA32_INL_H_ 566 #endif // V8_IA32_ASSEMBLER_IA32_INL_H_
OLDNEW
« no previous file with comments | « src/ia32/assembler-ia32.h ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698