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