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