OLD | NEW |
1 | 1 |
2 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 2 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
3 // All Rights Reserved. | 3 // All Rights Reserved. |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // - Redistributions of source code must retain the above copyright notice, | 9 // - Redistributions of source code must retain the above copyright notice, |
10 // this list of conditions and the following disclaimer. | 10 // this list of conditions and the following disclaimer. |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 Address Assembler::target_address_from_return_address(Address pc) { | 187 Address Assembler::target_address_from_return_address(Address pc) { |
188 return pc - kCallTargetAddressOffset; | 188 return pc - kCallTargetAddressOffset; |
189 } | 189 } |
190 | 190 |
191 | 191 |
192 Address Assembler::break_address_from_return_address(Address pc) { | 192 Address Assembler::break_address_from_return_address(Address pc) { |
193 return pc - Assembler::kPatchDebugBreakSlotReturnOffset; | 193 return pc - Assembler::kPatchDebugBreakSlotReturnOffset; |
194 } | 194 } |
195 | 195 |
196 | 196 |
| 197 void Assembler::deserialization_set_target_internal_reference_at( |
| 198 Address pc, Address target) { |
| 199 if (IsLui(instr_at(pc))) { |
| 200 // Encoded internal references are lui/ori load of 48-bit abolute address. |
| 201 Instr instr_lui = Assembler::instr_at(pc + 0 * Assembler::kInstrSize); |
| 202 Instr instr_ori = Assembler::instr_at(pc + 1 * Assembler::kInstrSize); |
| 203 Instr instr_ori2 = Assembler::instr_at(pc + 3 * Assembler::kInstrSize); |
| 204 DCHECK(Assembler::IsLui(instr_lui)); |
| 205 DCHECK(Assembler::IsOri(instr_ori)); |
| 206 DCHECK(Assembler::IsOri(instr_ori2)); |
| 207 instr_lui &= ~kImm16Mask; |
| 208 instr_ori &= ~kImm16Mask; |
| 209 instr_ori2 &= ~kImm16Mask; |
| 210 int64_t imm = reinterpret_cast<int64_t>(target); |
| 211 DCHECK((imm & 3) == 0); |
| 212 Assembler::instr_at_put(pc + 0 * Assembler::kInstrSize, |
| 213 instr_lui | ((imm >> 32) & kImm16Mask)); |
| 214 Assembler::instr_at_put(pc + 1 * Assembler::kInstrSize, |
| 215 instr_ori | ((imm >> 16) & kImm16Mask)); |
| 216 Assembler::instr_at_put(pc + 3 * Assembler::kInstrSize, |
| 217 instr_ori | (imm & kImm16Mask)); |
| 218 // Currently used only by deserializer, and all code will be flushed |
| 219 // after complete deserialization, no need to flush on each reference. |
| 220 } else { |
| 221 Memory::Address_at(pc) = target; |
| 222 } |
| 223 } |
| 224 |
| 225 |
197 Object* RelocInfo::target_object() { | 226 Object* RelocInfo::target_object() { |
198 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 227 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
199 return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_)); | 228 return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_)); |
200 } | 229 } |
201 | 230 |
202 | 231 |
203 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { | 232 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { |
204 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 233 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
205 return Handle<Object>(reinterpret_cast<Object**>( | 234 return Handle<Object>(reinterpret_cast<Object**>( |
206 Assembler::target_address_at(pc_, host_))); | 235 Assembler::target_address_at(pc_, host_))); |
(...skipping 19 matching lines...) Expand all Loading... |
226 Address RelocInfo::target_external_reference() { | 255 Address RelocInfo::target_external_reference() { |
227 DCHECK(rmode_ == EXTERNAL_REFERENCE); | 256 DCHECK(rmode_ == EXTERNAL_REFERENCE); |
228 return Assembler::target_address_at(pc_, host_); | 257 return Assembler::target_address_at(pc_, host_); |
229 } | 258 } |
230 | 259 |
231 | 260 |
232 Address RelocInfo::target_internal_reference() { | 261 Address RelocInfo::target_internal_reference() { |
233 if (rmode_ == INTERNAL_REFERENCE) { | 262 if (rmode_ == INTERNAL_REFERENCE) { |
234 return Memory::Address_at(pc_); | 263 return Memory::Address_at(pc_); |
235 } else { | 264 } else { |
| 265 // Encoded internal references are lui/ori load of 48-bit abolute address. |
236 DCHECK(rmode_ == INTERNAL_REFERENCE_ENCODED); | 266 DCHECK(rmode_ == INTERNAL_REFERENCE_ENCODED); |
237 Instr instr_lui = Assembler::instr_at(pc_ + 0 * Assembler::kInstrSize); | 267 Instr instr_lui = Assembler::instr_at(pc_ + 0 * Assembler::kInstrSize); |
238 Instr instr_ori = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize); | 268 Instr instr_ori = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize); |
239 Instr instr_ori2 = Assembler::instr_at(pc_ + 3 * Assembler::kInstrSize); | 269 Instr instr_ori2 = Assembler::instr_at(pc_ + 3 * Assembler::kInstrSize); |
240 DCHECK(Assembler::IsLui(instr_lui)); | 270 DCHECK(Assembler::IsLui(instr_lui)); |
241 DCHECK(Assembler::IsOri(instr_ori)); | 271 DCHECK(Assembler::IsOri(instr_ori)); |
242 DCHECK(Assembler::IsOri(instr_ori2)); | 272 DCHECK(Assembler::IsOri(instr_ori2)); |
243 int64_t imm = (instr_lui & static_cast<int64_t>(kImm16Mask)) << 32; | 273 int64_t imm = (instr_lui & static_cast<int64_t>(kImm16Mask)) << 32; |
244 imm |= (instr_ori & static_cast<int64_t>(kImm16Mask)) << 16; | 274 imm |= (instr_ori & static_cast<int64_t>(kImm16Mask)) << 16; |
245 imm |= (instr_ori2 & static_cast<int64_t>(kImm16Mask)); | 275 imm |= (instr_ori2 & static_cast<int64_t>(kImm16Mask)); |
246 return reinterpret_cast<Address>(imm); | 276 return reinterpret_cast<Address>(imm); |
247 } | 277 } |
248 } | 278 } |
249 | 279 |
250 | 280 |
251 void RelocInfo::set_target_internal_reference(Address target) { | 281 Address RelocInfo::target_internal_reference_address() { |
252 if (rmode_ == INTERNAL_REFERENCE) { | 282 DCHECK(rmode_ == INTERNAL_REFERENCE || rmode_ == INTERNAL_REFERENCE_ENCODED); |
253 Memory::Address_at(pc_) = target; | 283 return reinterpret_cast<Address>(pc_); |
254 } else { | |
255 // Encoded internal references are lui/ori load of 48-bit abolute address. | |
256 DCHECK(rmode_ == INTERNAL_REFERENCE_ENCODED); | |
257 Instr instr_lui = Assembler::instr_at(pc_ + 0 * Assembler::kInstrSize); | |
258 Instr instr_ori = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize); | |
259 Instr instr_ori2 = Assembler::instr_at(pc_ + 3 * Assembler::kInstrSize); | |
260 DCHECK(Assembler::IsLui(instr_lui)); | |
261 DCHECK(Assembler::IsOri(instr_ori)); | |
262 DCHECK(Assembler::IsOri(instr_ori2)); | |
263 instr_lui &= ~kImm16Mask; | |
264 instr_ori &= ~kImm16Mask; | |
265 instr_ori2 &= ~kImm16Mask; | |
266 int64_t imm = reinterpret_cast<int64_t>(target); | |
267 DCHECK((imm & 3) == 0); | |
268 Assembler::instr_at_put(pc_ + 0 * Assembler::kInstrSize, | |
269 instr_lui | ((imm >> 32) & kImm16Mask)); | |
270 Assembler::instr_at_put(pc_ + 1 * Assembler::kInstrSize, | |
271 instr_ori | ((imm >> 16) & kImm16Mask)); | |
272 Assembler::instr_at_put(pc_ + 3 * Assembler::kInstrSize, | |
273 instr_ori | (imm & kImm16Mask)); | |
274 // Currently used only by deserializer, and all code will be flushed | |
275 // after complete deserialization, no need to flush on each reference. | |
276 } | |
277 } | 284 } |
278 | 285 |
279 | 286 |
280 Address RelocInfo::target_runtime_entry(Assembler* origin) { | 287 Address RelocInfo::target_runtime_entry(Assembler* origin) { |
281 DCHECK(IsRuntimeEntry(rmode_)); | 288 DCHECK(IsRuntimeEntry(rmode_)); |
282 return target_address(); | 289 return target_address(); |
283 } | 290 } |
284 | 291 |
285 | 292 |
286 void RelocInfo::set_target_runtime_entry(Address target, | 293 void RelocInfo::set_target_runtime_entry(Address target, |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 return reinterpret_cast<Object**>(pc_ + 6 * Assembler::kInstrSize); | 388 return reinterpret_cast<Object**>(pc_ + 6 * Assembler::kInstrSize); |
382 } | 389 } |
383 | 390 |
384 | 391 |
385 void RelocInfo::set_call_object(Object* target) { | 392 void RelocInfo::set_call_object(Object* target) { |
386 *call_object_address() = target; | 393 *call_object_address() = target; |
387 } | 394 } |
388 | 395 |
389 | 396 |
390 void RelocInfo::WipeOut() { | 397 void RelocInfo::WipeOut() { |
391 DCHECK(IsEmbeddedObject(rmode_) || | 398 DCHECK(IsEmbeddedObject(rmode_) || IsCodeTarget(rmode_) || |
392 IsCodeTarget(rmode_) || | 399 IsRuntimeEntry(rmode_) || IsExternalReference(rmode_) || |
393 IsRuntimeEntry(rmode_) || | 400 IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_)); |
394 IsExternalReference(rmode_)); | 401 if (IsInternalReference(rmode_)) { |
395 Assembler::set_target_address_at(pc_, host_, NULL); | 402 Memory::Address_at(pc_) = NULL; |
| 403 } else if (IsInternalReferenceEncoded(rmode_)) { |
| 404 Instr instr_lui = Assembler::instr_at(pc_ + 0 * Assembler::kInstrSize); |
| 405 Instr instr_ori = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize); |
| 406 Instr instr_ori2 = Assembler::instr_at(pc_ + 3 * Assembler::kInstrSize); |
| 407 DCHECK(Assembler::IsLui(instr_lui)); |
| 408 DCHECK(Assembler::IsOri(instr_ori)); |
| 409 DCHECK(Assembler::IsOri(instr_ori2)); |
| 410 instr_lui &= ~kImm16Mask; |
| 411 instr_ori &= ~kImm16Mask; |
| 412 instr_ori2 &= ~kImm16Mask; |
| 413 int64_t imm = 0; |
| 414 Assembler::instr_at_put(pc_ + 0 * Assembler::kInstrSize, |
| 415 instr_lui | ((imm >> 32) & kImm16Mask)); |
| 416 Assembler::instr_at_put(pc_ + 1 * Assembler::kInstrSize, |
| 417 instr_ori | ((imm >> 16) & kImm16Mask)); |
| 418 Assembler::instr_at_put(pc_ + 3 * Assembler::kInstrSize, |
| 419 instr_ori | (imm & kImm16Mask)); |
| 420 // Currently used only by deserializer, and all code will be flushed |
| 421 // after complete deserialization, no need to flush on each reference. |
| 422 } else { |
| 423 Assembler::set_target_address_at(pc_, host_, NULL); |
| 424 } |
396 } | 425 } |
397 | 426 |
398 | 427 |
399 bool RelocInfo::IsPatchedReturnSequence() { | 428 bool RelocInfo::IsPatchedReturnSequence() { |
400 Instr instr0 = Assembler::instr_at(pc_); // lui. | 429 Instr instr0 = Assembler::instr_at(pc_); // lui. |
401 Instr instr1 = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize); // ori. | 430 Instr instr1 = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize); // ori. |
402 Instr instr2 = Assembler::instr_at(pc_ + 2 * Assembler::kInstrSize); // dsll. | 431 Instr instr2 = Assembler::instr_at(pc_ + 2 * Assembler::kInstrSize); // dsll. |
403 Instr instr3 = Assembler::instr_at(pc_ + 3 * Assembler::kInstrSize); // ori. | 432 Instr instr3 = Assembler::instr_at(pc_ + 3 * Assembler::kInstrSize); // ori. |
404 Instr instr4 = Assembler::instr_at(pc_ + 4 * Assembler::kInstrSize); // jalr. | 433 Instr instr4 = Assembler::instr_at(pc_ + 4 * Assembler::kInstrSize); // jalr. |
405 | 434 |
(...skipping 15 matching lines...) Expand all Loading... |
421 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { | 450 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { |
422 RelocInfo::Mode mode = rmode(); | 451 RelocInfo::Mode mode = rmode(); |
423 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 452 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
424 visitor->VisitEmbeddedPointer(this); | 453 visitor->VisitEmbeddedPointer(this); |
425 } else if (RelocInfo::IsCodeTarget(mode)) { | 454 } else if (RelocInfo::IsCodeTarget(mode)) { |
426 visitor->VisitCodeTarget(this); | 455 visitor->VisitCodeTarget(this); |
427 } else if (mode == RelocInfo::CELL) { | 456 } else if (mode == RelocInfo::CELL) { |
428 visitor->VisitCell(this); | 457 visitor->VisitCell(this); |
429 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 458 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
430 visitor->VisitExternalReference(this); | 459 visitor->VisitExternalReference(this); |
| 460 } else if (mode == RelocInfo::INTERNAL_REFERENCE || |
| 461 mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) { |
| 462 visitor->VisitInternalReference(this); |
431 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 463 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
432 visitor->VisitCodeAgeSequence(this); | 464 visitor->VisitCodeAgeSequence(this); |
433 } else if (((RelocInfo::IsJSReturn(mode) && | 465 } else if (((RelocInfo::IsJSReturn(mode) && |
434 IsPatchedReturnSequence()) || | 466 IsPatchedReturnSequence()) || |
435 (RelocInfo::IsDebugBreakSlot(mode) && | 467 (RelocInfo::IsDebugBreakSlot(mode) && |
436 IsPatchedDebugBreakSlotSequence())) && | 468 IsPatchedDebugBreakSlotSequence())) && |
437 isolate->debug()->has_break_points()) { | 469 isolate->debug()->has_break_points()) { |
438 visitor->VisitDebugTarget(this); | 470 visitor->VisitDebugTarget(this); |
439 } else if (RelocInfo::IsRuntimeEntry(mode)) { | 471 } else if (RelocInfo::IsRuntimeEntry(mode)) { |
440 visitor->VisitRuntimeEntry(this); | 472 visitor->VisitRuntimeEntry(this); |
441 } | 473 } |
442 } | 474 } |
443 | 475 |
444 | 476 |
445 template<typename StaticVisitor> | 477 template<typename StaticVisitor> |
446 void RelocInfo::Visit(Heap* heap) { | 478 void RelocInfo::Visit(Heap* heap) { |
447 RelocInfo::Mode mode = rmode(); | 479 RelocInfo::Mode mode = rmode(); |
448 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 480 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
449 StaticVisitor::VisitEmbeddedPointer(heap, this); | 481 StaticVisitor::VisitEmbeddedPointer(heap, this); |
450 } else if (RelocInfo::IsCodeTarget(mode)) { | 482 } else if (RelocInfo::IsCodeTarget(mode)) { |
451 StaticVisitor::VisitCodeTarget(heap, this); | 483 StaticVisitor::VisitCodeTarget(heap, this); |
452 } else if (mode == RelocInfo::CELL) { | 484 } else if (mode == RelocInfo::CELL) { |
453 StaticVisitor::VisitCell(heap, this); | 485 StaticVisitor::VisitCell(heap, this); |
454 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 486 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
455 StaticVisitor::VisitExternalReference(this); | 487 StaticVisitor::VisitExternalReference(this); |
| 488 } else if (mode == RelocInfo::INTERNAL_REFERENCE || |
| 489 mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) { |
| 490 StaticVisitor::VisitInternalReference(this); |
456 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 491 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
457 StaticVisitor::VisitCodeAgeSequence(heap, this); | 492 StaticVisitor::VisitCodeAgeSequence(heap, this); |
458 } else if (heap->isolate()->debug()->has_break_points() && | 493 } else if (heap->isolate()->debug()->has_break_points() && |
459 ((RelocInfo::IsJSReturn(mode) && | 494 ((RelocInfo::IsJSReturn(mode) && |
460 IsPatchedReturnSequence()) || | 495 IsPatchedReturnSequence()) || |
461 (RelocInfo::IsDebugBreakSlot(mode) && | 496 (RelocInfo::IsDebugBreakSlot(mode) && |
462 IsPatchedDebugBreakSlotSequence()))) { | 497 IsPatchedDebugBreakSlotSequence()))) { |
463 StaticVisitor::VisitDebugTarget(heap, this); | 498 StaticVisitor::VisitDebugTarget(heap, this); |
464 } else if (RelocInfo::IsRuntimeEntry(mode)) { | 499 } else if (RelocInfo::IsRuntimeEntry(mode)) { |
465 StaticVisitor::VisitRuntimeEntry(this); | 500 StaticVisitor::VisitRuntimeEntry(this); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 } | 536 } |
502 *reinterpret_cast<uint64_t*>(pc_) = x; | 537 *reinterpret_cast<uint64_t*>(pc_) = x; |
503 pc_ += kInstrSize * 2; | 538 pc_ += kInstrSize * 2; |
504 CheckTrampolinePoolQuick(); | 539 CheckTrampolinePoolQuick(); |
505 } | 540 } |
506 | 541 |
507 | 542 |
508 } } // namespace v8::internal | 543 } } // namespace v8::internal |
509 | 544 |
510 #endif // V8_MIPS_ASSEMBLER_MIPS_INL_H_ | 545 #endif // V8_MIPS_ASSEMBLER_MIPS_INL_H_ |
OLD | NEW |