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 27 matching lines...) Expand all Loading... | |
38 #define V8_IA32_ASSEMBLER_IA32_INL_H_ | 38 #define V8_IA32_ASSEMBLER_IA32_INL_H_ |
39 | 39 |
40 #include "ia32/assembler-ia32.h" | 40 #include "ia32/assembler-ia32.h" |
41 | 41 |
42 #include "cpu.h" | 42 #include "cpu.h" |
43 #include "debug.h" | 43 #include "debug.h" |
44 | 44 |
45 namespace v8 { | 45 namespace v8 { |
46 namespace internal { | 46 namespace internal { |
47 | 47 |
48 static const byte kCallOpcode = 0xE8; | |
48 | 49 |
49 // The modes possibly affected by apply must be in kApplyMask. | 50 // The modes possibly affected by apply must be in kApplyMask. |
50 void RelocInfo::apply(intptr_t delta) { | 51 void RelocInfo::apply(intptr_t delta) { |
51 if (rmode_ == RUNTIME_ENTRY || IsCodeTarget(rmode_)) { | 52 if (rmode_ == RUNTIME_ENTRY || IsCodeTarget(rmode_)) { |
52 int32_t* p = reinterpret_cast<int32_t*>(pc_); | 53 int32_t* p = reinterpret_cast<int32_t*>(pc_); |
53 *p -= delta; // Relocate entry. | 54 *p -= delta; // Relocate entry. |
54 CPU::FlushICache(p, sizeof(uint32_t)); | 55 CPU::FlushICache(p, sizeof(uint32_t)); |
56 } else if (rmode_ == CODE_AGE_SEQUENCE) { | |
57 if (*pc_ == kCallOpcode) { | |
58 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | |
59 *p -= delta; // Relocate entry. | |
60 CPU::FlushICache(p, sizeof(uint32_t)); | |
61 } | |
55 } else if (rmode_ == JS_RETURN && IsPatchedReturnSequence()) { | 62 } else if (rmode_ == JS_RETURN && IsPatchedReturnSequence()) { |
56 // Special handling of js_return when a break point is set (call | 63 // Special handling of js_return when a break point is set (call |
57 // instruction has been inserted). | 64 // instruction has been inserted). |
58 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | 65 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); |
59 *p -= delta; // Relocate entry. | 66 *p -= delta; // Relocate entry. |
60 CPU::FlushICache(p, sizeof(uint32_t)); | 67 CPU::FlushICache(p, sizeof(uint32_t)); |
61 } else if (rmode_ == DEBUG_BREAK_SLOT && IsPatchedDebugBreakSlotSequence()) { | 68 } else if (rmode_ == DEBUG_BREAK_SLOT && IsPatchedDebugBreakSlotSequence()) { |
62 // Special handling of a debug break slot when a break point is set (call | 69 // Special handling of a debug break slot when a break point is set (call |
63 // instruction has been inserted). | 70 // instruction has been inserted). |
64 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | 71 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
162 CPU::FlushICache(pc_, sizeof(Address)); | 169 CPU::FlushICache(pc_, sizeof(Address)); |
163 if (mode == UPDATE_WRITE_BARRIER && host() != NULL) { | 170 if (mode == UPDATE_WRITE_BARRIER && host() != NULL) { |
164 // TODO(1550) We are passing NULL as a slot because cell can never be on | 171 // TODO(1550) We are passing NULL as a slot because cell can never be on |
165 // evacuation candidate. | 172 // evacuation candidate. |
166 host()->GetHeap()->incremental_marking()->RecordWrite( | 173 host()->GetHeap()->incremental_marking()->RecordWrite( |
167 host(), NULL, cell); | 174 host(), NULL, cell); |
168 } | 175 } |
169 } | 176 } |
170 | 177 |
171 | 178 |
179 Code* RelocInfo::code_age_stub() { | |
Michael Starzinger
2012/09/21 09:43:19
ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
danno
2012/10/25 10:07:23
Done.
| |
180 if (*pc_ == kCallOpcode) { | |
181 return Code::GetCodeFromTargetAddress( | |
182 Assembler::target_address_at(pc_ + 1)); | |
183 } else { | |
184 return NULL; | |
185 } | |
186 } | |
187 | |
188 | |
189 void RelocInfo::set_code_age_stub(Code* stub) { | |
Michael Starzinger
2012/09/21 09:43:19
ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
danno
2012/10/25 10:07:23
Done.
| |
190 Assembler::set_target_address_at(pc_ + 1, stub->instruction_start()); | |
191 } | |
192 | |
193 | |
172 Address RelocInfo::call_address() { | 194 Address RelocInfo::call_address() { |
173 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 195 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
174 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 196 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
175 return Assembler::target_address_at(pc_ + 1); | 197 return Assembler::target_address_at(pc_ + 1); |
176 } | 198 } |
177 | 199 |
178 | 200 |
179 void RelocInfo::set_call_address(Address target) { | 201 void RelocInfo::set_call_address(Address target) { |
180 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 202 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
181 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 203 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
(...skipping 17 matching lines...) Expand all Loading... | |
199 | 221 |
200 | 222 |
201 Object** RelocInfo::call_object_address() { | 223 Object** RelocInfo::call_object_address() { |
202 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 224 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
203 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 225 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
204 return reinterpret_cast<Object**>(pc_ + 1); | 226 return reinterpret_cast<Object**>(pc_ + 1); |
205 } | 227 } |
206 | 228 |
207 | 229 |
208 bool RelocInfo::IsPatchedReturnSequence() { | 230 bool RelocInfo::IsPatchedReturnSequence() { |
209 return *pc_ == 0xE8; | 231 return *pc_ == kCallOpcode; |
210 } | 232 } |
211 | 233 |
212 | 234 |
213 bool RelocInfo::IsPatchedDebugBreakSlotSequence() { | 235 bool RelocInfo::IsPatchedDebugBreakSlotSequence() { |
214 return !Assembler::IsNop(pc()); | 236 return !Assembler::IsNop(pc()); |
215 } | 237 } |
216 | 238 |
217 | 239 |
218 void RelocInfo::Visit(ObjectVisitor* visitor) { | 240 void RelocInfo::Visit(ObjectVisitor* visitor) { |
219 RelocInfo::Mode mode = rmode(); | 241 RelocInfo::Mode mode = rmode(); |
220 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 242 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
221 visitor->VisitEmbeddedPointer(this); | 243 visitor->VisitEmbeddedPointer(this); |
222 CPU::FlushICache(pc_, sizeof(Address)); | 244 CPU::FlushICache(pc_, sizeof(Address)); |
223 } else if (RelocInfo::IsCodeTarget(mode)) { | 245 } else if (RelocInfo::IsCodeTarget(mode)) { |
224 visitor->VisitCodeTarget(this); | 246 visitor->VisitCodeTarget(this); |
225 } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { | 247 } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { |
226 visitor->VisitGlobalPropertyCell(this); | 248 visitor->VisitGlobalPropertyCell(this); |
227 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 249 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
228 visitor->VisitExternalReference(this); | 250 visitor->VisitExternalReference(this); |
229 CPU::FlushICache(pc_, sizeof(Address)); | 251 CPU::FlushICache(pc_, sizeof(Address)); |
230 #ifdef ENABLE_DEBUGGER_SUPPORT | 252 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
253 visitor->VisitCodeAgeSequence(this); | |
254 #ifdef ENABLE_DEBUGGER_SUPPORT | |
231 // TODO(isolates): Get a cached isolate below. | 255 // TODO(isolates): Get a cached isolate below. |
232 } else if (((RelocInfo::IsJSReturn(mode) && | 256 } else if (((RelocInfo::IsJSReturn(mode) && |
233 IsPatchedReturnSequence()) || | 257 IsPatchedReturnSequence()) || |
234 (RelocInfo::IsDebugBreakSlot(mode) && | 258 (RelocInfo::IsDebugBreakSlot(mode) && |
235 IsPatchedDebugBreakSlotSequence())) && | 259 IsPatchedDebugBreakSlotSequence())) && |
236 Isolate::Current()->debug()->has_break_points()) { | 260 Isolate::Current()->debug()->has_break_points()) { |
237 visitor->VisitDebugTarget(this); | 261 visitor->VisitDebugTarget(this); |
238 #endif | 262 #endif |
239 } else if (mode == RelocInfo::RUNTIME_ENTRY) { | 263 } else if (mode == RelocInfo::RUNTIME_ENTRY) { |
240 visitor->VisitRuntimeEntry(this); | 264 visitor->VisitRuntimeEntry(this); |
241 } | 265 } |
242 } | 266 } |
243 | 267 |
244 | 268 |
245 template<typename StaticVisitor> | 269 template<typename StaticVisitor> |
246 void RelocInfo::Visit(Heap* heap) { | 270 void RelocInfo::Visit(Heap* heap) { |
247 RelocInfo::Mode mode = rmode(); | 271 RelocInfo::Mode mode = rmode(); |
248 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 272 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
249 StaticVisitor::VisitEmbeddedPointer(heap, this); | 273 StaticVisitor::VisitEmbeddedPointer(heap, this); |
250 CPU::FlushICache(pc_, sizeof(Address)); | 274 CPU::FlushICache(pc_, sizeof(Address)); |
251 } else if (RelocInfo::IsCodeTarget(mode)) { | 275 } else if (RelocInfo::IsCodeTarget(mode)) { |
252 StaticVisitor::VisitCodeTarget(heap, this); | 276 StaticVisitor::VisitCodeTarget(heap, this); |
253 } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { | 277 } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { |
254 StaticVisitor::VisitGlobalPropertyCell(heap, this); | 278 StaticVisitor::VisitGlobalPropertyCell(heap, this); |
255 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 279 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
256 StaticVisitor::VisitExternalReference(this); | 280 StaticVisitor::VisitExternalReference(this); |
257 CPU::FlushICache(pc_, sizeof(Address)); | 281 CPU::FlushICache(pc_, sizeof(Address)); |
282 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | |
283 StaticVisitor::VisitCodeAgeSequence(heap, this); | |
258 #ifdef ENABLE_DEBUGGER_SUPPORT | 284 #ifdef ENABLE_DEBUGGER_SUPPORT |
259 } else if (heap->isolate()->debug()->has_break_points() && | 285 } else if (heap->isolate()->debug()->has_break_points() && |
260 ((RelocInfo::IsJSReturn(mode) && | 286 ((RelocInfo::IsJSReturn(mode) && |
261 IsPatchedReturnSequence()) || | 287 IsPatchedReturnSequence()) || |
262 (RelocInfo::IsDebugBreakSlot(mode) && | 288 (RelocInfo::IsDebugBreakSlot(mode) && |
263 IsPatchedDebugBreakSlotSequence()))) { | 289 IsPatchedDebugBreakSlotSequence()))) { |
264 StaticVisitor::VisitDebugTarget(heap, this); | 290 StaticVisitor::VisitDebugTarget(heap, this); |
265 #endif | 291 #endif |
266 } else if (mode == RelocInfo::RUNTIME_ENTRY) { | 292 } else if (mode == RelocInfo::RUNTIME_ENTRY) { |
267 StaticVisitor::VisitRuntimeEntry(this); | 293 StaticVisitor::VisitRuntimeEntry(this); |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
461 | 487 |
462 Operand::Operand(int32_t disp, RelocInfo::Mode rmode) { | 488 Operand::Operand(int32_t disp, RelocInfo::Mode rmode) { |
463 // [disp/r] | 489 // [disp/r] |
464 set_modrm(0, ebp); | 490 set_modrm(0, ebp); |
465 set_dispr(disp, rmode); | 491 set_dispr(disp, rmode); |
466 } | 492 } |
467 | 493 |
468 } } // namespace v8::internal | 494 } } // namespace v8::internal |
469 | 495 |
470 #endif // V8_IA32_ASSEMBLER_IA32_INL_H_ | 496 #endif // V8_IA32_ASSEMBLER_IA32_INL_H_ |
OLD | NEW |