| 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 |