OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 void Assembler::emit_optional_rex_32(Register rm_reg) { | 198 void Assembler::emit_optional_rex_32(Register rm_reg) { |
199 if (rm_reg.high_bit()) emit(0x41); | 199 if (rm_reg.high_bit()) emit(0x41); |
200 } | 200 } |
201 | 201 |
202 | 202 |
203 void Assembler::emit_optional_rex_32(const Operand& op) { | 203 void Assembler::emit_optional_rex_32(const Operand& op) { |
204 if (op.rex_ != 0) emit(0x40 | op.rex_); | 204 if (op.rex_ != 0) emit(0x40 | op.rex_); |
205 } | 205 } |
206 | 206 |
207 | 207 |
208 Address Assembler::target_address_at(Address pc, | 208 Address Assembler::target_address_at(Address pc) { |
209 ConstantPoolArray* constant_pool) { | |
210 return Memory::int32_at(pc) + pc + 4; | 209 return Memory::int32_at(pc) + pc + 4; |
211 } | 210 } |
212 | 211 |
213 | 212 |
214 void Assembler::set_target_address_at(Address pc, | 213 void Assembler::set_target_address_at(Address pc, Address target) { |
215 ConstantPoolArray* constant_pool, | |
216 Address target) { | |
217 Memory::int32_at(pc) = static_cast<int32_t>(target - pc - 4); | 214 Memory::int32_at(pc) = static_cast<int32_t>(target - pc - 4); |
218 CPU::FlushICache(pc, sizeof(int32_t)); | 215 CPU::FlushICache(pc, sizeof(int32_t)); |
219 } | 216 } |
220 | 217 |
221 | 218 |
222 Address Assembler::target_address_from_return_address(Address pc) { | 219 Address Assembler::target_address_from_return_address(Address pc) { |
223 return pc - kCallTargetAddressOffset; | 220 return pc - kCallTargetAddressOffset; |
224 } | 221 } |
225 | 222 |
226 | 223 |
(...skipping 24 matching lines...) Expand all Loading... |
251 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | 248 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); |
252 *p -= static_cast<int32_t>(delta); // Relocate entry. | 249 *p -= static_cast<int32_t>(delta); // Relocate entry. |
253 CPU::FlushICache(p, sizeof(uint32_t)); | 250 CPU::FlushICache(p, sizeof(uint32_t)); |
254 } | 251 } |
255 } | 252 } |
256 } | 253 } |
257 | 254 |
258 | 255 |
259 Address RelocInfo::target_address() { | 256 Address RelocInfo::target_address() { |
260 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 257 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
261 return Assembler::target_address_at(pc_, host_); | 258 return Assembler::target_address_at(pc_); |
262 } | 259 } |
263 | 260 |
264 | 261 |
265 Address RelocInfo::target_address_address() { | 262 Address RelocInfo::target_address_address() { |
266 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) | 263 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) |
267 || rmode_ == EMBEDDED_OBJECT | 264 || rmode_ == EMBEDDED_OBJECT |
268 || rmode_ == EXTERNAL_REFERENCE); | 265 || rmode_ == EXTERNAL_REFERENCE); |
269 return reinterpret_cast<Address>(pc_); | 266 return reinterpret_cast<Address>(pc_); |
270 } | 267 } |
271 | 268 |
272 | 269 |
273 Address RelocInfo::constant_pool_entry_address() { | 270 Address RelocInfo::constant_pool_entry_address() { |
274 UNREACHABLE(); | 271 UNREACHABLE(); |
275 return NULL; | 272 return NULL; |
276 } | 273 } |
277 | 274 |
278 | 275 |
279 int RelocInfo::target_address_size() { | 276 int RelocInfo::target_address_size() { |
280 if (IsCodedSpecially()) { | 277 if (IsCodedSpecially()) { |
281 return Assembler::kSpecialTargetSize; | 278 return Assembler::kSpecialTargetSize; |
282 } else { | 279 } else { |
283 return kPointerSize; | 280 return kPointerSize; |
284 } | 281 } |
285 } | 282 } |
286 | 283 |
287 | 284 |
288 void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) { | 285 void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) { |
289 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 286 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
290 Assembler::set_target_address_at(pc_, host_, target); | 287 Assembler::set_target_address_at(pc_, target); |
291 if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) { | 288 if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) { |
292 Object* target_code = Code::GetCodeFromTargetAddress(target); | 289 Object* target_code = Code::GetCodeFromTargetAddress(target); |
293 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 290 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
294 host(), this, HeapObject::cast(target_code)); | 291 host(), this, HeapObject::cast(target_code)); |
295 } | 292 } |
296 } | 293 } |
297 | 294 |
298 | 295 |
299 Object* RelocInfo::target_object() { | 296 Object* RelocInfo::target_object() { |
300 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 297 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 host(), NULL, cell); | 368 host(), NULL, cell); |
372 } | 369 } |
373 } | 370 } |
374 | 371 |
375 | 372 |
376 void RelocInfo::WipeOut() { | 373 void RelocInfo::WipeOut() { |
377 if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_)) { | 374 if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_)) { |
378 Memory::Address_at(pc_) = NULL; | 375 Memory::Address_at(pc_) = NULL; |
379 } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { | 376 } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { |
380 // Effectively write zero into the relocation. | 377 // Effectively write zero into the relocation. |
381 Assembler::set_target_address_at(pc_, host_, pc_ + sizeof(int32_t)); | 378 Assembler::set_target_address_at(pc_, pc_ + sizeof(int32_t)); |
382 } else { | 379 } else { |
383 UNREACHABLE(); | 380 UNREACHABLE(); |
384 } | 381 } |
385 } | 382 } |
386 | 383 |
387 | 384 |
388 bool RelocInfo::IsPatchedReturnSequence() { | 385 bool RelocInfo::IsPatchedReturnSequence() { |
389 // The recognized call sequence is: | 386 // The recognized call sequence is: |
390 // movq(kScratchRegister, address); call(kScratchRegister); | 387 // movq(kScratchRegister, address); call(kScratchRegister); |
391 // It only needs to be distinguished from a return sequence | 388 // It only needs to be distinguished from a return sequence |
(...skipping 18 matching lines...) Expand all Loading... |
410 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 407 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
411 ASSERT(*pc_ == kCallOpcode); | 408 ASSERT(*pc_ == kCallOpcode); |
412 return origin->code_target_object_handle_at(pc_ + 1); | 409 return origin->code_target_object_handle_at(pc_ + 1); |
413 } | 410 } |
414 | 411 |
415 | 412 |
416 Code* RelocInfo::code_age_stub() { | 413 Code* RelocInfo::code_age_stub() { |
417 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 414 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
418 ASSERT(*pc_ == kCallOpcode); | 415 ASSERT(*pc_ == kCallOpcode); |
419 return Code::GetCodeFromTargetAddress( | 416 return Code::GetCodeFromTargetAddress( |
420 Assembler::target_address_at(pc_ + 1, host_)); | 417 Assembler::target_address_at(pc_ + 1)); |
421 } | 418 } |
422 | 419 |
423 | 420 |
424 void RelocInfo::set_code_age_stub(Code* stub) { | 421 void RelocInfo::set_code_age_stub(Code* stub) { |
425 ASSERT(*pc_ == kCallOpcode); | 422 ASSERT(*pc_ == kCallOpcode); |
426 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 423 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
427 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start()); | 424 Assembler::set_target_address_at(pc_ + 1, stub->instruction_start()); |
428 } | 425 } |
429 | 426 |
430 | 427 |
431 Address RelocInfo::call_address() { | 428 Address RelocInfo::call_address() { |
432 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 429 ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || |
433 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 430 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); |
434 return Memory::Address_at( | 431 return Memory::Address_at( |
435 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset); | 432 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset); |
436 } | 433 } |
437 | 434 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 ASSERT(len_ == 1 || len_ == 2); | 557 ASSERT(len_ == 1 || len_ == 2); |
561 int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); | 558 int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); |
562 *p = disp; | 559 *p = disp; |
563 len_ += sizeof(int32_t); | 560 len_ += sizeof(int32_t); |
564 } | 561 } |
565 | 562 |
566 | 563 |
567 } } // namespace v8::internal | 564 } } // namespace v8::internal |
568 | 565 |
569 #endif // V8_X64_ASSEMBLER_X64_INL_H_ | 566 #endif // V8_X64_ASSEMBLER_X64_INL_H_ |
OLD | NEW |