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 | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are 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 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 DCHECK(IsWasmGlobalReference(rmode_)); | 352 DCHECK(IsWasmGlobalReference(rmode_)); |
353 return Assembler::target_address_at(pc_, host_); | 353 return Assembler::target_address_at(pc_, host_); |
354 } | 354 } |
355 | 355 |
356 uint32_t RelocInfo::wasm_function_table_size_reference() { | 356 uint32_t RelocInfo::wasm_function_table_size_reference() { |
357 DCHECK(IsWasmFunctionTableSizeReference(rmode_)); | 357 DCHECK(IsWasmFunctionTableSizeReference(rmode_)); |
358 return reinterpret_cast<uint32_t>(Assembler::target_address_at(pc_, host_)); | 358 return reinterpret_cast<uint32_t>(Assembler::target_address_at(pc_, host_)); |
359 } | 359 } |
360 | 360 |
361 void RelocInfo::unchecked_update_wasm_memory_reference( | 361 void RelocInfo::unchecked_update_wasm_memory_reference( |
362 Address address, ICacheFlushMode flush_mode) { | 362 Isolate* isolate, Address address, ICacheFlushMode flush_mode) { |
363 Assembler::set_target_address_at(isolate_, pc_, host_, address, flush_mode); | 363 Assembler::set_target_address_at(isolate, pc_, host_, address, flush_mode); |
364 } | 364 } |
365 | 365 |
366 void RelocInfo::unchecked_update_wasm_size(uint32_t size, | 366 void RelocInfo::unchecked_update_wasm_size(Isolate* isolate, uint32_t size, |
367 ICacheFlushMode flush_mode) { | 367 ICacheFlushMode flush_mode) { |
368 Assembler::set_target_address_at(isolate_, pc_, host_, | 368 Assembler::set_target_address_at(isolate, pc_, host_, |
369 reinterpret_cast<Address>(size), flush_mode); | 369 reinterpret_cast<Address>(size), flush_mode); |
370 } | 370 } |
371 | 371 |
372 // ----------------------------------------------------------------------------- | 372 // ----------------------------------------------------------------------------- |
373 // Implementation of Operand and MemOperand | 373 // Implementation of Operand and MemOperand |
374 // See assembler-arm-inl.h for inlined constructors | 374 // See assembler-arm-inl.h for inlined constructors |
375 | 375 |
376 Operand::Operand(Handle<Object> handle) { | 376 Operand::Operand(Handle<Object> handle) { |
377 AllowDeferredHandleDereference using_raw_address; | 377 AllowDeferredHandleDereference using_raw_address; |
378 rm_ = no_reg; | 378 rm_ = no_reg; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 const Instr kLdrRegFpOffsetPattern = | 544 const Instr kLdrRegFpOffsetPattern = |
545 al | B26 | L | Offset | Register::kCode_fp * B16; | 545 al | B26 | L | Offset | Register::kCode_fp * B16; |
546 const Instr kStrRegFpOffsetPattern = | 546 const Instr kStrRegFpOffsetPattern = |
547 al | B26 | Offset | Register::kCode_fp * B16; | 547 al | B26 | Offset | Register::kCode_fp * B16; |
548 const Instr kLdrRegFpNegOffsetPattern = | 548 const Instr kLdrRegFpNegOffsetPattern = |
549 al | B26 | L | NegOffset | Register::kCode_fp * B16; | 549 al | B26 | L | NegOffset | Register::kCode_fp * B16; |
550 const Instr kStrRegFpNegOffsetPattern = | 550 const Instr kStrRegFpNegOffsetPattern = |
551 al | B26 | NegOffset | Register::kCode_fp * B16; | 551 al | B26 | NegOffset | Register::kCode_fp * B16; |
552 const Instr kLdrStrInstrTypeMask = 0xffff0000; | 552 const Instr kLdrStrInstrTypeMask = 0xffff0000; |
553 | 553 |
554 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) | 554 Assembler::Assembler(IsolateData isolate_data, void* buffer, int buffer_size) |
555 : AssemblerBase(isolate, buffer, buffer_size), | 555 : AssemblerBase(isolate_data, buffer, buffer_size), |
556 recorded_ast_id_(TypeFeedbackId::None()), | 556 recorded_ast_id_(TypeFeedbackId::None()), |
557 pending_32_bit_constants_(), | 557 pending_32_bit_constants_(), |
558 pending_64_bit_constants_(), | 558 pending_64_bit_constants_(), |
559 constant_pool_builder_(kLdrMaxReachBits, kVldrMaxReachBits) { | 559 constant_pool_builder_(kLdrMaxReachBits, kVldrMaxReachBits) { |
560 pending_32_bit_constants_.reserve(kMinNumPendingConstants); | 560 pending_32_bit_constants_.reserve(kMinNumPendingConstants); |
561 pending_64_bit_constants_.reserve(kMinNumPendingConstants); | 561 pending_64_bit_constants_.reserve(kMinNumPendingConstants); |
562 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); | 562 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); |
563 next_buffer_check_ = 0; | 563 next_buffer_check_ = 0; |
564 const_pool_blocked_nesting_ = 0; | 564 const_pool_blocked_nesting_ = 0; |
565 no_const_pool_before_ = 0; | 565 no_const_pool_before_ = 0; |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
934 // For ARMv6: target24 => target8_2:target8_1:target8_0 | 934 // For ARMv6: target24 => target8_2:target8_1:target8_0 |
935 // mov dst, #target8_0 | 935 // mov dst, #target8_0 |
936 // orr dst, dst, #target8_1 << 8 | 936 // orr dst, dst, #target8_1 << 8 |
937 // orr dst, dst, #target8_2 << 16 | 937 // orr dst, dst, #target8_2 << 16 |
938 | 938 |
939 uint32_t target24 = target_pos + (Code::kHeaderSize - kHeapObjectTag); | 939 uint32_t target24 = target_pos + (Code::kHeaderSize - kHeapObjectTag); |
940 DCHECK(is_uint24(target24)); | 940 DCHECK(is_uint24(target24)); |
941 if (is_uint8(target24)) { | 941 if (is_uint8(target24)) { |
942 // If the target fits in a byte then only patch with a mov | 942 // If the target fits in a byte then only patch with a mov |
943 // instruction. | 943 // instruction. |
944 CodePatcher patcher(isolate(), reinterpret_cast<byte*>(buffer_ + pos), 1, | 944 PatchingAssembler patcher(isolate_data(), |
945 CodePatcher::DONT_FLUSH); | 945 reinterpret_cast<byte*>(buffer_ + pos), 1); |
946 patcher.masm()->mov(dst, Operand(target24)); | 946 patcher.mov(dst, Operand(target24)); |
947 } else { | 947 } else { |
948 uint16_t target16_0 = target24 & kImm16Mask; | 948 uint16_t target16_0 = target24 & kImm16Mask; |
949 uint16_t target16_1 = target24 >> 16; | 949 uint16_t target16_1 = target24 >> 16; |
950 if (CpuFeatures::IsSupported(ARMv7)) { | 950 if (CpuFeatures::IsSupported(ARMv7)) { |
951 // Patch with movw/movt. | 951 // Patch with movw/movt. |
952 if (target16_1 == 0) { | 952 if (target16_1 == 0) { |
953 CodePatcher patcher(isolate(), reinterpret_cast<byte*>(buffer_ + pos), | 953 PatchingAssembler patcher(isolate_data(), |
954 1, CodePatcher::DONT_FLUSH); | 954 reinterpret_cast<byte*>(buffer_ + pos), 1); |
955 CpuFeatureScope scope(patcher.masm(), ARMv7); | 955 CpuFeatureScope scope(&patcher, ARMv7); |
956 patcher.masm()->movw(dst, target16_0); | 956 patcher.movw(dst, target16_0); |
957 } else { | 957 } else { |
958 CodePatcher patcher(isolate(), reinterpret_cast<byte*>(buffer_ + pos), | 958 PatchingAssembler patcher(isolate_data(), |
959 2, CodePatcher::DONT_FLUSH); | 959 reinterpret_cast<byte*>(buffer_ + pos), 2); |
960 CpuFeatureScope scope(patcher.masm(), ARMv7); | 960 CpuFeatureScope scope(&patcher, ARMv7); |
961 patcher.masm()->movw(dst, target16_0); | 961 patcher.movw(dst, target16_0); |
962 patcher.masm()->movt(dst, target16_1); | 962 patcher.movt(dst, target16_1); |
963 } | 963 } |
964 } else { | 964 } else { |
965 // Patch with a sequence of mov/orr/orr instructions. | 965 // Patch with a sequence of mov/orr/orr instructions. |
966 uint8_t target8_0 = target16_0 & kImm8Mask; | 966 uint8_t target8_0 = target16_0 & kImm8Mask; |
967 uint8_t target8_1 = target16_0 >> 8; | 967 uint8_t target8_1 = target16_0 >> 8; |
968 uint8_t target8_2 = target16_1 & kImm8Mask; | 968 uint8_t target8_2 = target16_1 & kImm8Mask; |
969 if (target8_2 == 0) { | 969 if (target8_2 == 0) { |
970 CodePatcher patcher(isolate(), reinterpret_cast<byte*>(buffer_ + pos), | 970 PatchingAssembler patcher(isolate_data(), |
971 2, CodePatcher::DONT_FLUSH); | 971 reinterpret_cast<byte*>(buffer_ + pos), 2); |
972 patcher.masm()->mov(dst, Operand(target8_0)); | 972 patcher.mov(dst, Operand(target8_0)); |
973 patcher.masm()->orr(dst, dst, Operand(target8_1 << 8)); | 973 patcher.orr(dst, dst, Operand(target8_1 << 8)); |
974 } else { | 974 } else { |
975 CodePatcher patcher(isolate(), reinterpret_cast<byte*>(buffer_ + pos), | 975 PatchingAssembler patcher(isolate_data(), |
976 3, CodePatcher::DONT_FLUSH); | 976 reinterpret_cast<byte*>(buffer_ + pos), 3); |
977 patcher.masm()->mov(dst, Operand(target8_0)); | 977 patcher.mov(dst, Operand(target8_0)); |
978 patcher.masm()->orr(dst, dst, Operand(target8_1 << 8)); | 978 patcher.orr(dst, dst, Operand(target8_1 << 8)); |
979 patcher.masm()->orr(dst, dst, Operand(target8_2 << 16)); | 979 patcher.orr(dst, dst, Operand(target8_2 << 16)); |
980 } | 980 } |
981 } | 981 } |
982 } | 982 } |
983 return; | 983 return; |
984 } | 984 } |
985 int imm26 = target_pos - (pos + kPcLoadDelta); | 985 int imm26 = target_pos - (pos + kPcLoadDelta); |
986 DCHECK_EQ(5 * B25, instr & 7 * B25); // b, bl, or blx imm24 | 986 DCHECK_EQ(5 * B25, instr & 7 * B25); // b, bl, or blx imm24 |
987 if (Instruction::ConditionField(instr) == kSpecialCondition) { | 987 if (Instruction::ConditionField(instr) == kSpecialCondition) { |
988 // blx uses bit 24 to encode bit 2 of imm26 | 988 // blx uses bit 24 to encode bit 2 of imm26 |
989 DCHECK_EQ(0, imm26 & 1); | 989 DCHECK_EQ(0, imm26 & 1); |
(...skipping 4001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4991 // Don't record external references unless the heap will be serialized. | 4991 // Don't record external references unless the heap will be serialized. |
4992 (rmode == RelocInfo::EXTERNAL_REFERENCE && !serializer_enabled() && | 4992 (rmode == RelocInfo::EXTERNAL_REFERENCE && !serializer_enabled() && |
4993 !emit_debug_code())) { | 4993 !emit_debug_code())) { |
4994 return; | 4994 return; |
4995 } | 4995 } |
4996 DCHECK(buffer_space() >= kMaxRelocSize); // too late to grow buffer here | 4996 DCHECK(buffer_space() >= kMaxRelocSize); // too late to grow buffer here |
4997 if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { | 4997 if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { |
4998 data = RecordedAstId().ToInt(); | 4998 data = RecordedAstId().ToInt(); |
4999 ClearRecordedAstId(); | 4999 ClearRecordedAstId(); |
5000 } | 5000 } |
5001 RelocInfo rinfo(isolate(), pc_, rmode, data, NULL); | 5001 RelocInfo rinfo(pc_, rmode, data, NULL); |
5002 reloc_info_writer.Write(&rinfo); | 5002 reloc_info_writer.Write(&rinfo); |
5003 } | 5003 } |
5004 | 5004 |
5005 | 5005 |
5006 ConstantPoolEntry::Access Assembler::ConstantPoolAddEntry(int position, | 5006 ConstantPoolEntry::Access Assembler::ConstantPoolAddEntry(int position, |
5007 RelocInfo::Mode rmode, | 5007 RelocInfo::Mode rmode, |
5008 intptr_t value) { | 5008 intptr_t value) { |
5009 DCHECK(rmode != RelocInfo::COMMENT && rmode != RelocInfo::CONST_POOL && | 5009 DCHECK(rmode != RelocInfo::COMMENT && rmode != RelocInfo::CONST_POOL && |
5010 rmode != RelocInfo::NONE64); | 5010 rmode != RelocInfo::NONE64); |
5011 bool sharing_ok = RelocInfo::IsNone(rmode) || | 5011 bool sharing_ok = RelocInfo::IsNone(rmode) || |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5345 instr_at_put(pc, SetVldrDRegisterImmediateOffset(instr, offset)); | 5345 instr_at_put(pc, SetVldrDRegisterImmediateOffset(instr, offset)); |
5346 } else { | 5346 } else { |
5347 // Instruction to patch must be 'ldr rd, [pp, #0]'. | 5347 // Instruction to patch must be 'ldr rd, [pp, #0]'. |
5348 DCHECK((IsLdrPpImmediateOffset(instr) && | 5348 DCHECK((IsLdrPpImmediateOffset(instr) && |
5349 GetLdrRegisterImmediateOffset(instr) == 0)); | 5349 GetLdrRegisterImmediateOffset(instr) == 0)); |
5350 DCHECK(is_uint12(offset)); | 5350 DCHECK(is_uint12(offset)); |
5351 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); | 5351 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); |
5352 } | 5352 } |
5353 } | 5353 } |
5354 | 5354 |
| 5355 PatchingAssembler::PatchingAssembler(IsolateData isolate_data, byte* address, |
| 5356 int instructions) |
| 5357 : Assembler(isolate_data, address, instructions * kInstrSize + kGap) { |
| 5358 DCHECK_EQ(reloc_info_writer.pos(), buffer_ + buffer_size_); |
| 5359 } |
| 5360 |
| 5361 PatchingAssembler::~PatchingAssembler() { |
| 5362 // Check that we don't have any pending constant pools. |
| 5363 DCHECK(pending_32_bit_constants_.empty()); |
| 5364 DCHECK(pending_64_bit_constants_.empty()); |
| 5365 |
| 5366 // Check that the code was patched as expected. |
| 5367 DCHECK_EQ(pc_, buffer_ + buffer_size_ - kGap); |
| 5368 DCHECK_EQ(reloc_info_writer.pos(), buffer_ + buffer_size_); |
| 5369 } |
| 5370 |
| 5371 void PatchingAssembler::Emit(Address addr) { |
| 5372 emit(reinterpret_cast<Instr>(addr)); |
| 5373 } |
| 5374 |
| 5375 void PatchingAssembler::FlushICache(Isolate* isolate) { |
| 5376 Assembler::FlushICache(isolate, buffer_, buffer_size_ - kGap); |
| 5377 } |
5355 | 5378 |
5356 } // namespace internal | 5379 } // namespace internal |
5357 } // namespace v8 | 5380 } // namespace v8 |
5358 | 5381 |
5359 #endif // V8_TARGET_ARCH_ARM | 5382 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |