Chromium Code Reviews| 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 |