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 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 const Instr kLdrRegFpOffsetPattern = | 476 const Instr kLdrRegFpOffsetPattern = |
477 al | B26 | L | Offset | Register::kCode_fp * B16; | 477 al | B26 | L | Offset | Register::kCode_fp * B16; |
478 const Instr kStrRegFpOffsetPattern = | 478 const Instr kStrRegFpOffsetPattern = |
479 al | B26 | Offset | Register::kCode_fp * B16; | 479 al | B26 | Offset | Register::kCode_fp * B16; |
480 const Instr kLdrRegFpNegOffsetPattern = | 480 const Instr kLdrRegFpNegOffsetPattern = |
481 al | B26 | L | NegOffset | Register::kCode_fp * B16; | 481 al | B26 | L | NegOffset | Register::kCode_fp * B16; |
482 const Instr kStrRegFpNegOffsetPattern = | 482 const Instr kStrRegFpNegOffsetPattern = |
483 al | B26 | NegOffset | Register::kCode_fp * B16; | 483 al | B26 | NegOffset | Register::kCode_fp * B16; |
484 const Instr kLdrStrInstrTypeMask = 0xffff0000; | 484 const Instr kLdrStrInstrTypeMask = 0xffff0000; |
485 | 485 |
486 | |
487 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) | 486 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) |
488 : AssemblerBase(isolate, buffer, buffer_size), | 487 : AssemblerBase(isolate, buffer, buffer_size), |
489 recorded_ast_id_(TypeFeedbackId::None()), | 488 recorded_ast_id_(TypeFeedbackId::None()), |
490 pending_32_bit_constants_(&pending_32_bit_constants_buffer_[0]), | 489 pending_32_bit_constants_(), |
491 pending_64_bit_constants_(&pending_64_bit_constants_buffer_[0]), | 490 pending_64_bit_constants_(), |
492 constant_pool_builder_(kLdrMaxReachBits, kVldrMaxReachBits), | 491 constant_pool_builder_(kLdrMaxReachBits, kVldrMaxReachBits), |
493 positions_recorder_(this) { | 492 positions_recorder_(this) { |
| 493 pending_32_bit_constants_.reserve(kMinNumPendingConstants); |
| 494 pending_64_bit_constants_.reserve(kMinNumPendingConstants); |
494 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); | 495 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); |
495 num_pending_32_bit_constants_ = 0; | |
496 num_pending_64_bit_constants_ = 0; | |
497 next_buffer_check_ = 0; | 496 next_buffer_check_ = 0; |
498 const_pool_blocked_nesting_ = 0; | 497 const_pool_blocked_nesting_ = 0; |
499 no_const_pool_before_ = 0; | 498 no_const_pool_before_ = 0; |
500 first_const_pool_32_use_ = -1; | 499 first_const_pool_32_use_ = -1; |
501 first_const_pool_64_use_ = -1; | 500 first_const_pool_64_use_ = -1; |
502 last_bound_pos_ = 0; | 501 last_bound_pos_ = 0; |
503 ClearRecordedAstId(); | 502 ClearRecordedAstId(); |
504 } | 503 } |
505 | 504 |
506 | 505 |
507 Assembler::~Assembler() { | 506 Assembler::~Assembler() { |
508 DCHECK(const_pool_blocked_nesting_ == 0); | 507 DCHECK(const_pool_blocked_nesting_ == 0); |
509 if (pending_32_bit_constants_ != &pending_32_bit_constants_buffer_[0]) { | |
510 delete[] pending_32_bit_constants_; | |
511 } | |
512 if (pending_64_bit_constants_ != &pending_64_bit_constants_buffer_[0]) { | |
513 delete[] pending_64_bit_constants_; | |
514 } | |
515 } | 508 } |
516 | 509 |
517 | 510 |
518 void Assembler::GetCode(CodeDesc* desc) { | 511 void Assembler::GetCode(CodeDesc* desc) { |
519 reloc_info_writer.Finish(); | 512 reloc_info_writer.Finish(); |
520 | 513 |
521 // Emit constant pool if necessary. | 514 // Emit constant pool if necessary. |
522 int constant_pool_offset = 0; | 515 int constant_pool_offset = 0; |
523 if (FLAG_enable_embedded_constant_pool) { | 516 if (FLAG_enable_embedded_constant_pool) { |
524 constant_pool_offset = EmitEmbeddedConstantPool(); | 517 constant_pool_offset = EmitEmbeddedConstantPool(); |
525 } else { | 518 } else { |
526 CheckConstPool(true, false); | 519 CheckConstPool(true, false); |
527 DCHECK(num_pending_32_bit_constants_ == 0); | 520 DCHECK(pending_32_bit_constants_.empty()); |
528 DCHECK(num_pending_64_bit_constants_ == 0); | 521 DCHECK(pending_64_bit_constants_.empty()); |
529 } | 522 } |
530 // Set up code descriptor. | 523 // Set up code descriptor. |
531 desc->buffer = buffer_; | 524 desc->buffer = buffer_; |
532 desc->buffer_size = buffer_size_; | 525 desc->buffer_size = buffer_size_; |
533 desc->instr_size = pc_offset(); | 526 desc->instr_size = pc_offset(); |
534 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); | 527 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); |
535 desc->constant_pool_size = | 528 desc->constant_pool_size = |
536 (constant_pool_offset ? desc->instr_size - constant_pool_offset : 0); | 529 (constant_pool_offset ? desc->instr_size - constant_pool_offset : 0); |
537 desc->origin = this; | 530 desc->origin = this; |
538 } | 531 } |
(...skipping 3334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3873 | 3866 |
3874 // None of our relocation types are pc relative pointing outside the code | 3867 // None of our relocation types are pc relative pointing outside the code |
3875 // buffer nor pc absolute pointing inside the code buffer, so there is no need | 3868 // buffer nor pc absolute pointing inside the code buffer, so there is no need |
3876 // to relocate any emitted relocation entries. | 3869 // to relocate any emitted relocation entries. |
3877 } | 3870 } |
3878 | 3871 |
3879 | 3872 |
3880 void Assembler::db(uint8_t data) { | 3873 void Assembler::db(uint8_t data) { |
3881 // db is used to write raw data. The constant pool should be emitted or | 3874 // db is used to write raw data. The constant pool should be emitted or |
3882 // blocked before using db. | 3875 // blocked before using db. |
3883 DCHECK(is_const_pool_blocked() || (num_pending_32_bit_constants_ == 0)); | 3876 DCHECK(is_const_pool_blocked() || pending_32_bit_constants_.empty()); |
3884 DCHECK(is_const_pool_blocked() || (num_pending_64_bit_constants_ == 0)); | 3877 DCHECK(is_const_pool_blocked() || pending_64_bit_constants_.empty()); |
3885 CheckBuffer(); | 3878 CheckBuffer(); |
3886 *reinterpret_cast<uint8_t*>(pc_) = data; | 3879 *reinterpret_cast<uint8_t*>(pc_) = data; |
3887 pc_ += sizeof(uint8_t); | 3880 pc_ += sizeof(uint8_t); |
3888 } | 3881 } |
3889 | 3882 |
3890 | 3883 |
3891 void Assembler::dd(uint32_t data) { | 3884 void Assembler::dd(uint32_t data) { |
3892 // dd is used to write raw data. The constant pool should be emitted or | 3885 // dd is used to write raw data. The constant pool should be emitted or |
3893 // blocked before using dd. | 3886 // blocked before using dd. |
3894 DCHECK(is_const_pool_blocked() || (num_pending_32_bit_constants_ == 0)); | 3887 DCHECK(is_const_pool_blocked() || pending_32_bit_constants_.empty()); |
3895 DCHECK(is_const_pool_blocked() || (num_pending_64_bit_constants_ == 0)); | 3888 DCHECK(is_const_pool_blocked() || pending_64_bit_constants_.empty()); |
3896 CheckBuffer(); | 3889 CheckBuffer(); |
3897 *reinterpret_cast<uint32_t*>(pc_) = data; | 3890 *reinterpret_cast<uint32_t*>(pc_) = data; |
3898 pc_ += sizeof(uint32_t); | 3891 pc_ += sizeof(uint32_t); |
3899 } | 3892 } |
3900 | 3893 |
3901 | 3894 |
3902 void Assembler::dq(uint64_t value) { | 3895 void Assembler::dq(uint64_t value) { |
3903 // dq is used to write raw data. The constant pool should be emitted or | 3896 // dq is used to write raw data. The constant pool should be emitted or |
3904 // blocked before using dq. | 3897 // blocked before using dq. |
3905 DCHECK(is_const_pool_blocked() || (num_pending_32_bit_constants_ == 0)); | 3898 DCHECK(is_const_pool_blocked() || pending_32_bit_constants_.empty()); |
3906 DCHECK(is_const_pool_blocked() || (num_pending_64_bit_constants_ == 0)); | 3899 DCHECK(is_const_pool_blocked() || pending_64_bit_constants_.empty()); |
3907 CheckBuffer(); | 3900 CheckBuffer(); |
3908 *reinterpret_cast<uint64_t*>(pc_) = value; | 3901 *reinterpret_cast<uint64_t*>(pc_) = value; |
3909 pc_ += sizeof(uint64_t); | 3902 pc_ += sizeof(uint64_t); |
3910 } | 3903 } |
3911 | 3904 |
3912 | 3905 |
3913 void Assembler::emit_code_stub_address(Code* stub) { | 3906 void Assembler::emit_code_stub_address(Code* stub) { |
3914 CheckBuffer(); | 3907 CheckBuffer(); |
3915 *reinterpret_cast<uint32_t*>(pc_) = | 3908 *reinterpret_cast<uint32_t*>(pc_) = |
3916 reinterpret_cast<uint32_t>(stub->instruction_start()); | 3909 reinterpret_cast<uint32_t>(stub->instruction_start()); |
(...skipping 20 matching lines...) Expand all Loading... |
3937 | 3930 |
3938 ConstantPoolEntry::Access Assembler::ConstantPoolAddEntry(int position, | 3931 ConstantPoolEntry::Access Assembler::ConstantPoolAddEntry(int position, |
3939 RelocInfo::Mode rmode, | 3932 RelocInfo::Mode rmode, |
3940 intptr_t value) { | 3933 intptr_t value) { |
3941 DCHECK(rmode != RelocInfo::COMMENT && rmode != RelocInfo::POSITION && | 3934 DCHECK(rmode != RelocInfo::COMMENT && rmode != RelocInfo::POSITION && |
3942 rmode != RelocInfo::STATEMENT_POSITION && | 3935 rmode != RelocInfo::STATEMENT_POSITION && |
3943 rmode != RelocInfo::CONST_POOL && rmode != RelocInfo::NONE64); | 3936 rmode != RelocInfo::CONST_POOL && rmode != RelocInfo::NONE64); |
3944 bool sharing_ok = RelocInfo::IsNone(rmode) || | 3937 bool sharing_ok = RelocInfo::IsNone(rmode) || |
3945 !(serializer_enabled() || rmode < RelocInfo::CELL); | 3938 !(serializer_enabled() || rmode < RelocInfo::CELL); |
3946 if (FLAG_enable_embedded_constant_pool) { | 3939 if (FLAG_enable_embedded_constant_pool) { |
3947 return constant_pool_builder_.AddEntry(position, value, sharing_ok); | 3940 return constant_pool_builder_.AddEntry(position, value, sharing_ok, rmode); |
3948 } else { | 3941 } else { |
3949 DCHECK(num_pending_32_bit_constants_ < kMaxNumPending32Constants); | 3942 DCHECK(pending_32_bit_constants_.size() < kMaxNumPending32Constants); |
3950 if (num_pending_32_bit_constants_ == 0) { | 3943 if (pending_32_bit_constants_.empty()) { |
3951 first_const_pool_32_use_ = position; | 3944 first_const_pool_32_use_ = position; |
3952 } else if (num_pending_32_bit_constants_ == kMinNumPendingConstants && | 3945 } else if (pending_32_bit_constants_.size() == kMinNumPendingConstants) { |
3953 pending_32_bit_constants_ == | 3946 pending_32_bit_constants_.reserve(kMaxNumPending32Constants); |
3954 &pending_32_bit_constants_buffer_[0]) { | |
3955 // Inline buffer is full, switch to dynamically allocated buffer. | |
3956 pending_32_bit_constants_ = | |
3957 new ConstantPoolEntry[kMaxNumPending32Constants]; | |
3958 std::copy(&pending_32_bit_constants_buffer_[0], | |
3959 &pending_32_bit_constants_buffer_[kMinNumPendingConstants], | |
3960 &pending_32_bit_constants_[0]); | |
3961 } | 3947 } |
3962 ConstantPoolEntry entry(position, value, sharing_ok); | 3948 ConstantPoolEntry entry(position, value, sharing_ok, rmode); |
3963 pending_32_bit_constants_[num_pending_32_bit_constants_++] = entry; | 3949 pending_32_bit_constants_.push_back(entry); |
3964 | 3950 |
3965 // Make sure the constant pool is not emitted in place of the next | 3951 // Make sure the constant pool is not emitted in place of the next |
3966 // instruction for which we just recorded relocation info. | 3952 // instruction for which we just recorded relocation info. |
3967 BlockConstPoolFor(1); | 3953 BlockConstPoolFor(1); |
3968 return ConstantPoolEntry::REGULAR; | 3954 return ConstantPoolEntry::REGULAR; |
3969 } | 3955 } |
3970 } | 3956 } |
3971 | 3957 |
3972 | 3958 |
3973 ConstantPoolEntry::Access Assembler::ConstantPoolAddEntry(int position, | 3959 ConstantPoolEntry::Access Assembler::ConstantPoolAddEntry(int position, |
3974 double value) { | 3960 double value) { |
3975 if (FLAG_enable_embedded_constant_pool) { | 3961 if (FLAG_enable_embedded_constant_pool) { |
3976 return constant_pool_builder_.AddEntry(position, value); | 3962 return constant_pool_builder_.AddEntry(position, value); |
3977 } else { | 3963 } else { |
3978 DCHECK(num_pending_64_bit_constants_ < kMaxNumPending64Constants); | 3964 DCHECK(pending_64_bit_constants_.size() < kMaxNumPending64Constants); |
3979 if (num_pending_64_bit_constants_ == 0) { | 3965 if (pending_64_bit_constants_.empty()) { |
3980 first_const_pool_64_use_ = position; | 3966 first_const_pool_64_use_ = position; |
3981 } else if (num_pending_64_bit_constants_ == kMinNumPendingConstants && | 3967 } else if (pending_64_bit_constants_.size() == kMinNumPendingConstants) { |
3982 pending_64_bit_constants_ == | |
3983 &pending_64_bit_constants_buffer_[0]) { | |
3984 // Inline buffer is full, switch to dynamically allocated buffer. | 3968 // Inline buffer is full, switch to dynamically allocated buffer. |
3985 pending_64_bit_constants_ = | 3969 pending_64_bit_constants_.reserve(kMaxNumPending64Constants); |
3986 new ConstantPoolEntry[kMaxNumPending64Constants]; | |
3987 std::copy(&pending_64_bit_constants_buffer_[0], | |
3988 &pending_64_bit_constants_buffer_[kMinNumPendingConstants], | |
3989 &pending_64_bit_constants_[0]); | |
3990 } | 3970 } |
3991 ConstantPoolEntry entry(position, value); | 3971 ConstantPoolEntry entry(position, value); |
3992 pending_64_bit_constants_[num_pending_64_bit_constants_++] = entry; | 3972 pending_64_bit_constants_.push_back(entry); |
3993 | 3973 |
3994 // Make sure the constant pool is not emitted in place of the next | 3974 // Make sure the constant pool is not emitted in place of the next |
3995 // instruction for which we just recorded relocation info. | 3975 // instruction for which we just recorded relocation info. |
3996 BlockConstPoolFor(1); | 3976 BlockConstPoolFor(1); |
3997 return ConstantPoolEntry::REGULAR; | 3977 return ConstantPoolEntry::REGULAR; |
3998 } | 3978 } |
3999 } | 3979 } |
4000 | 3980 |
4001 | 3981 |
4002 void Assembler::BlockConstPoolFor(int instructions) { | 3982 void Assembler::BlockConstPoolFor(int instructions) { |
4003 if (FLAG_enable_embedded_constant_pool) { | 3983 if (FLAG_enable_embedded_constant_pool) { |
4004 // Should be a no-op if using an embedded constant pool. | 3984 // Should be a no-op if using an embedded constant pool. |
4005 DCHECK(num_pending_32_bit_constants_ == 0); | 3985 DCHECK(pending_32_bit_constants_.empty()); |
4006 DCHECK(num_pending_64_bit_constants_ == 0); | 3986 DCHECK(pending_64_bit_constants_.empty()); |
4007 return; | 3987 return; |
4008 } | 3988 } |
4009 | 3989 |
4010 int pc_limit = pc_offset() + instructions * kInstrSize; | 3990 int pc_limit = pc_offset() + instructions * kInstrSize; |
4011 if (no_const_pool_before_ < pc_limit) { | 3991 if (no_const_pool_before_ < pc_limit) { |
4012 // Max pool start (if we need a jump and an alignment). | 3992 // Max pool start (if we need a jump and an alignment). |
4013 #ifdef DEBUG | 3993 #ifdef DEBUG |
4014 int start = pc_limit + kInstrSize + 2 * kPointerSize; | 3994 int start = pc_limit + kInstrSize + 2 * kPointerSize; |
4015 DCHECK((num_pending_32_bit_constants_ == 0) || | 3995 DCHECK(pending_32_bit_constants_.empty() || |
4016 (start - first_const_pool_32_use_ + | 3996 (start - first_const_pool_32_use_ + |
4017 num_pending_64_bit_constants_ * kDoubleSize < | 3997 pending_64_bit_constants_.size() * kDoubleSize < |
4018 kMaxDistToIntPool)); | 3998 kMaxDistToIntPool)); |
4019 DCHECK((num_pending_64_bit_constants_ == 0) || | 3999 DCHECK(pending_64_bit_constants_.empty() || |
4020 (start - first_const_pool_64_use_ < kMaxDistToFPPool)); | 4000 (start - first_const_pool_64_use_ < kMaxDistToFPPool)); |
4021 #endif | 4001 #endif |
4022 no_const_pool_before_ = pc_limit; | 4002 no_const_pool_before_ = pc_limit; |
4023 } | 4003 } |
4024 | 4004 |
4025 if (next_buffer_check_ < no_const_pool_before_) { | 4005 if (next_buffer_check_ < no_const_pool_before_) { |
4026 next_buffer_check_ = no_const_pool_before_; | 4006 next_buffer_check_ = no_const_pool_before_; |
4027 } | 4007 } |
4028 } | 4008 } |
4029 | 4009 |
4030 | 4010 |
4031 void Assembler::CheckConstPool(bool force_emit, bool require_jump) { | 4011 void Assembler::CheckConstPool(bool force_emit, bool require_jump) { |
4032 if (FLAG_enable_embedded_constant_pool) { | 4012 if (FLAG_enable_embedded_constant_pool) { |
4033 // Should be a no-op if using an embedded constant pool. | 4013 // Should be a no-op if using an embedded constant pool. |
4034 DCHECK(num_pending_32_bit_constants_ == 0); | 4014 DCHECK(pending_32_bit_constants_.empty()); |
4035 DCHECK(num_pending_64_bit_constants_ == 0); | 4015 DCHECK(pending_64_bit_constants_.empty()); |
4036 return; | 4016 return; |
4037 } | 4017 } |
4038 | 4018 |
4039 // Some short sequence of instruction mustn't be broken up by constant pool | 4019 // Some short sequence of instruction mustn't be broken up by constant pool |
4040 // emission, such sequences are protected by calls to BlockConstPoolFor and | 4020 // emission, such sequences are protected by calls to BlockConstPoolFor and |
4041 // BlockConstPoolScope. | 4021 // BlockConstPoolScope. |
4042 if (is_const_pool_blocked()) { | 4022 if (is_const_pool_blocked()) { |
4043 // Something is wrong if emission is forced and blocked at the same time. | 4023 // Something is wrong if emission is forced and blocked at the same time. |
4044 DCHECK(!force_emit); | 4024 DCHECK(!force_emit); |
4045 return; | 4025 return; |
4046 } | 4026 } |
4047 | 4027 |
4048 // There is nothing to do if there are no pending constant pool entries. | 4028 // There is nothing to do if there are no pending constant pool entries. |
4049 if ((num_pending_32_bit_constants_ == 0) && | 4029 if (pending_32_bit_constants_.empty() && pending_64_bit_constants_.empty()) { |
4050 (num_pending_64_bit_constants_ == 0)) { | |
4051 // Calculate the offset of the next check. | 4030 // Calculate the offset of the next check. |
4052 next_buffer_check_ = pc_offset() + kCheckPoolInterval; | 4031 next_buffer_check_ = pc_offset() + kCheckPoolInterval; |
4053 return; | 4032 return; |
4054 } | 4033 } |
4055 | 4034 |
4056 // Check that the code buffer is large enough before emitting the constant | 4035 // Check that the code buffer is large enough before emitting the constant |
4057 // pool (include the jump over the pool and the constant pool marker and | 4036 // pool (include the jump over the pool and the constant pool marker and |
4058 // the gap to the relocation information). | 4037 // the gap to the relocation information). |
4059 int jump_instr = require_jump ? kInstrSize : 0; | 4038 int jump_instr = require_jump ? kInstrSize : 0; |
4060 int size_up_to_marker = jump_instr + kInstrSize; | 4039 int size_up_to_marker = jump_instr + kInstrSize; |
4061 int estimated_size_after_marker = | 4040 int estimated_size_after_marker = |
4062 num_pending_32_bit_constants_ * kPointerSize; | 4041 pending_32_bit_constants_.size() * kPointerSize; |
4063 bool has_int_values = (num_pending_32_bit_constants_ > 0); | 4042 bool has_int_values = !pending_32_bit_constants_.empty(); |
4064 bool has_fp_values = (num_pending_64_bit_constants_ > 0); | 4043 bool has_fp_values = !pending_64_bit_constants_.empty(); |
4065 bool require_64_bit_align = false; | 4044 bool require_64_bit_align = false; |
4066 if (has_fp_values) { | 4045 if (has_fp_values) { |
4067 require_64_bit_align = | 4046 require_64_bit_align = |
4068 !IsAligned(reinterpret_cast<intptr_t>(pc_ + size_up_to_marker), | 4047 !IsAligned(reinterpret_cast<intptr_t>(pc_ + size_up_to_marker), |
4069 kDoubleAlignment); | 4048 kDoubleAlignment); |
4070 if (require_64_bit_align) { | 4049 if (require_64_bit_align) { |
4071 estimated_size_after_marker += kInstrSize; | 4050 estimated_size_after_marker += kInstrSize; |
4072 } | 4051 } |
4073 estimated_size_after_marker += num_pending_64_bit_constants_ * kDoubleSize; | 4052 estimated_size_after_marker += |
| 4053 pending_64_bit_constants_.size() * kDoubleSize; |
4074 } | 4054 } |
4075 int estimated_size = size_up_to_marker + estimated_size_after_marker; | 4055 int estimated_size = size_up_to_marker + estimated_size_after_marker; |
4076 | 4056 |
4077 // We emit a constant pool when: | 4057 // We emit a constant pool when: |
4078 // * requested to do so by parameter force_emit (e.g. after each function). | 4058 // * requested to do so by parameter force_emit (e.g. after each function). |
4079 // * the distance from the first instruction accessing the constant pool to | 4059 // * the distance from the first instruction accessing the constant pool to |
4080 // any of the constant pool entries will exceed its limit the next | 4060 // any of the constant pool entries will exceed its limit the next |
4081 // time the pool is checked. This is overly restrictive, but we don't emit | 4061 // time the pool is checked. This is overly restrictive, but we don't emit |
4082 // constant pool entries in-order so it's conservatively correct. | 4062 // constant pool entries in-order so it's conservatively correct. |
4083 // * the instruction doesn't require a jump after itself to jump over the | 4063 // * the instruction doesn't require a jump after itself to jump over the |
4084 // constant pool, and we're getting close to running out of range. | 4064 // constant pool, and we're getting close to running out of range. |
4085 if (!force_emit) { | 4065 if (!force_emit) { |
4086 DCHECK(has_fp_values || has_int_values); | 4066 DCHECK(has_fp_values || has_int_values); |
4087 bool need_emit = false; | 4067 bool need_emit = false; |
4088 if (has_fp_values) { | 4068 if (has_fp_values) { |
4089 // The 64-bit constants are always emitted before the 32-bit constants, so | 4069 // The 64-bit constants are always emitted before the 32-bit constants, so |
4090 // we can ignore the effect of the 32-bit constants on estimated_size. | 4070 // we can ignore the effect of the 32-bit constants on estimated_size. |
4091 int dist64 = pc_offset() + estimated_size - | 4071 int dist64 = pc_offset() + estimated_size - |
4092 num_pending_32_bit_constants_ * kPointerSize - | 4072 pending_32_bit_constants_.size() * kPointerSize - |
4093 first_const_pool_64_use_; | 4073 first_const_pool_64_use_; |
4094 if ((dist64 >= kMaxDistToFPPool - kCheckPoolInterval) || | 4074 if ((dist64 >= kMaxDistToFPPool - kCheckPoolInterval) || |
4095 (!require_jump && (dist64 >= kMaxDistToFPPool / 2))) { | 4075 (!require_jump && (dist64 >= kMaxDistToFPPool / 2))) { |
4096 need_emit = true; | 4076 need_emit = true; |
4097 } | 4077 } |
4098 } | 4078 } |
4099 if (has_int_values) { | 4079 if (has_int_values) { |
4100 int dist32 = pc_offset() + estimated_size - first_const_pool_32_use_; | 4080 int dist32 = pc_offset() + estimated_size - first_const_pool_32_use_; |
4101 if ((dist32 >= kMaxDistToIntPool - kCheckPoolInterval) || | 4081 if ((dist32 >= kMaxDistToIntPool - kCheckPoolInterval) || |
4102 (!require_jump && (dist32 >= kMaxDistToIntPool / 2))) { | 4082 (!require_jump && (dist32 >= kMaxDistToIntPool / 2))) { |
4103 need_emit = true; | 4083 need_emit = true; |
4104 } | 4084 } |
4105 } | 4085 } |
4106 if (!need_emit) return; | 4086 if (!need_emit) return; |
4107 } | 4087 } |
4108 | 4088 |
4109 // Deduplicate constants. | 4089 // Deduplicate constants. |
4110 int size_after_marker = estimated_size_after_marker; | 4090 int size_after_marker = estimated_size_after_marker; |
4111 for (int i = 0; i < num_pending_64_bit_constants_; i++) { | 4091 for (int i = 0; i < pending_64_bit_constants_.size(); i++) { |
4112 ConstantPoolEntry& entry = pending_64_bit_constants_[i]; | 4092 ConstantPoolEntry& entry = pending_64_bit_constants_[i]; |
4113 DCHECK(!entry.is_merged()); | 4093 DCHECK(!entry.is_merged()); |
4114 for (int j = 0; j < i; j++) { | 4094 for (int j = 0; j < i; j++) { |
4115 if (entry.value64() == pending_64_bit_constants_[j].value64()) { | 4095 if (entry.value64() == pending_64_bit_constants_[j].value64()) { |
4116 DCHECK(!pending_64_bit_constants_[j].is_merged()); | 4096 DCHECK(!pending_64_bit_constants_[j].is_merged()); |
4117 entry.set_merged_index(j); | 4097 entry.set_merged_index(j); |
4118 size_after_marker -= kDoubleSize; | 4098 size_after_marker -= kDoubleSize; |
4119 break; | 4099 break; |
4120 } | 4100 } |
4121 } | 4101 } |
4122 } | 4102 } |
4123 | 4103 |
4124 for (int i = 0; i < num_pending_32_bit_constants_; i++) { | 4104 for (int i = 0; i < pending_32_bit_constants_.size(); i++) { |
4125 ConstantPoolEntry& entry = pending_32_bit_constants_[i]; | 4105 ConstantPoolEntry& entry = pending_32_bit_constants_[i]; |
4126 DCHECK(!entry.is_merged()); | 4106 DCHECK(!entry.is_merged()); |
4127 if (!entry.sharing_ok()) continue; | 4107 if (!entry.sharing_ok()) continue; |
4128 for (int j = 0; j < i; j++) { | 4108 for (int j = 0; j < i; j++) { |
4129 if (entry.value() == pending_32_bit_constants_[j].value()) { | 4109 if (entry.MayBeMergedWith(pending_32_bit_constants_[j])) { |
4130 DCHECK(!pending_32_bit_constants_[j].is_merged()); | 4110 DCHECK(!pending_32_bit_constants_[j].is_merged()); |
4131 entry.set_merged_index(j); | 4111 entry.set_merged_index(j); |
4132 size_after_marker -= kPointerSize; | 4112 size_after_marker -= kPointerSize; |
4133 break; | 4113 break; |
4134 } | 4114 } |
4135 } | 4115 } |
4136 } | 4116 } |
4137 | 4117 |
4138 int size = size_up_to_marker + size_after_marker; | 4118 int size = size_up_to_marker + size_after_marker; |
4139 | 4119 |
(...skipping 19 matching lines...) Expand all Loading... |
4159 // The data size helps disassembly know what to print. | 4139 // The data size helps disassembly know what to print. |
4160 emit(kConstantPoolMarker | | 4140 emit(kConstantPoolMarker | |
4161 EncodeConstantPoolLength(size_after_marker / kPointerSize)); | 4141 EncodeConstantPoolLength(size_after_marker / kPointerSize)); |
4162 | 4142 |
4163 if (require_64_bit_align) { | 4143 if (require_64_bit_align) { |
4164 emit(kConstantPoolMarker); | 4144 emit(kConstantPoolMarker); |
4165 } | 4145 } |
4166 | 4146 |
4167 // Emit 64-bit constant pool entries first: their range is smaller than | 4147 // Emit 64-bit constant pool entries first: their range is smaller than |
4168 // 32-bit entries. | 4148 // 32-bit entries. |
4169 for (int i = 0; i < num_pending_64_bit_constants_; i++) { | 4149 for (int i = 0; i < pending_64_bit_constants_.size(); i++) { |
4170 ConstantPoolEntry& entry = pending_64_bit_constants_[i]; | 4150 ConstantPoolEntry& entry = pending_64_bit_constants_[i]; |
4171 | 4151 |
4172 Instr instr = instr_at(entry.position()); | 4152 Instr instr = instr_at(entry.position()); |
4173 // Instruction to patch must be 'vldr rd, [pc, #offset]' with offset == 0. | 4153 // Instruction to patch must be 'vldr rd, [pc, #offset]' with offset == 0. |
4174 DCHECK((IsVldrDPcImmediateOffset(instr) && | 4154 DCHECK((IsVldrDPcImmediateOffset(instr) && |
4175 GetVldrDRegisterImmediateOffset(instr) == 0)); | 4155 GetVldrDRegisterImmediateOffset(instr) == 0)); |
4176 | 4156 |
4177 int delta = pc_offset() - entry.position() - kPcLoadDelta; | 4157 int delta = pc_offset() - entry.position() - kPcLoadDelta; |
4178 DCHECK(is_uint10(delta)); | 4158 DCHECK(is_uint10(delta)); |
4179 | 4159 |
4180 if (entry.is_merged()) { | 4160 if (entry.is_merged()) { |
4181 ConstantPoolEntry& merged = | 4161 ConstantPoolEntry& merged = |
4182 pending_64_bit_constants_[entry.merged_index()]; | 4162 pending_64_bit_constants_[entry.merged_index()]; |
4183 DCHECK(entry.value64() == merged.value64()); | 4163 DCHECK(entry.value64() == merged.value64()); |
4184 Instr merged_instr = instr_at(merged.position()); | 4164 Instr merged_instr = instr_at(merged.position()); |
4185 DCHECK(IsVldrDPcImmediateOffset(merged_instr)); | 4165 DCHECK(IsVldrDPcImmediateOffset(merged_instr)); |
4186 delta = GetVldrDRegisterImmediateOffset(merged_instr); | 4166 delta = GetVldrDRegisterImmediateOffset(merged_instr); |
4187 delta += merged.position() - entry.position(); | 4167 delta += merged.position() - entry.position(); |
4188 } | 4168 } |
4189 instr_at_put(entry.position(), | 4169 instr_at_put(entry.position(), |
4190 SetVldrDRegisterImmediateOffset(instr, delta)); | 4170 SetVldrDRegisterImmediateOffset(instr, delta)); |
4191 if (!entry.is_merged()) { | 4171 if (!entry.is_merged()) { |
4192 DCHECK(IsAligned(reinterpret_cast<intptr_t>(pc_), kDoubleAlignment)); | 4172 DCHECK(IsAligned(reinterpret_cast<intptr_t>(pc_), kDoubleAlignment)); |
4193 dq(entry.value64()); | 4173 dq(entry.value64()); |
4194 } | 4174 } |
4195 } | 4175 } |
4196 | 4176 |
4197 // Emit 32-bit constant pool entries. | 4177 // Emit 32-bit constant pool entries. |
4198 for (int i = 0; i < num_pending_32_bit_constants_; i++) { | 4178 for (int i = 0; i < pending_32_bit_constants_.size(); i++) { |
4199 ConstantPoolEntry& entry = pending_32_bit_constants_[i]; | 4179 ConstantPoolEntry& entry = pending_32_bit_constants_[i]; |
4200 Instr instr = instr_at(entry.position()); | 4180 Instr instr = instr_at(entry.position()); |
4201 | 4181 |
4202 // 64-bit loads shouldn't get here. | 4182 // 64-bit loads shouldn't get here. |
4203 DCHECK(!IsVldrDPcImmediateOffset(instr)); | 4183 DCHECK(!IsVldrDPcImmediateOffset(instr)); |
4204 DCHECK(!IsMovW(instr)); | 4184 DCHECK(!IsMovW(instr)); |
4205 DCHECK(IsLdrPcImmediateOffset(instr) && | 4185 DCHECK(IsLdrPcImmediateOffset(instr) && |
4206 GetLdrRegisterImmediateOffset(instr) == 0); | 4186 GetLdrRegisterImmediateOffset(instr) == 0); |
4207 | 4187 |
4208 int delta = pc_offset() - entry.position() - kPcLoadDelta; | 4188 int delta = pc_offset() - entry.position() - kPcLoadDelta; |
4209 DCHECK(is_uint12(delta)); | 4189 DCHECK(is_uint12(delta)); |
4210 // 0 is the smallest delta: | 4190 // 0 is the smallest delta: |
4211 // ldr rd, [pc, #0] | 4191 // ldr rd, [pc, #0] |
4212 // constant pool marker | 4192 // constant pool marker |
4213 // data | 4193 // data |
4214 | 4194 |
4215 if (entry.is_merged()) { | 4195 if (entry.is_merged()) { |
4216 DCHECK(entry.sharing_ok()); | 4196 DCHECK(entry.sharing_ok()); |
4217 ConstantPoolEntry& merged = | 4197 ConstantPoolEntry& merged = |
4218 pending_32_bit_constants_[entry.merged_index()]; | 4198 pending_32_bit_constants_[entry.merged_index()]; |
4219 DCHECK(entry.value() == merged.value()); | 4199 DCHECK(entry.MayBeMergedWith(merged)); |
4220 Instr merged_instr = instr_at(merged.position()); | 4200 Instr merged_instr = instr_at(merged.position()); |
4221 DCHECK(IsLdrPcImmediateOffset(merged_instr)); | 4201 DCHECK(IsLdrPcImmediateOffset(merged_instr)); |
4222 delta = GetLdrRegisterImmediateOffset(merged_instr); | 4202 delta = GetLdrRegisterImmediateOffset(merged_instr); |
4223 delta += merged.position() - entry.position(); | 4203 delta += merged.position() - entry.position(); |
4224 } | 4204 } |
4225 instr_at_put(entry.position(), | 4205 instr_at_put(entry.position(), |
4226 SetLdrRegisterImmediateOffset(instr, delta)); | 4206 SetLdrRegisterImmediateOffset(instr, delta)); |
4227 if (!entry.is_merged()) { | 4207 if (!entry.is_merged()) { |
4228 emit(entry.value()); | 4208 emit(entry.value()); |
4229 } | 4209 } |
4230 } | 4210 } |
4231 | 4211 |
4232 num_pending_32_bit_constants_ = 0; | 4212 pending_32_bit_constants_.clear(); |
4233 num_pending_64_bit_constants_ = 0; | 4213 pending_64_bit_constants_.clear(); |
4234 first_const_pool_32_use_ = -1; | 4214 first_const_pool_32_use_ = -1; |
4235 first_const_pool_64_use_ = -1; | 4215 first_const_pool_64_use_ = -1; |
4236 | 4216 |
4237 RecordComment("]"); | 4217 RecordComment("]"); |
4238 | 4218 |
4239 DCHECK_EQ(size, SizeOfCodeGeneratedSince(&size_check)); | 4219 DCHECK_EQ(size, SizeOfCodeGeneratedSince(&size_check)); |
4240 | 4220 |
4241 if (after_pool.is_linked()) { | 4221 if (after_pool.is_linked()) { |
4242 bind(&after_pool); | 4222 bind(&after_pool); |
4243 } | 4223 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4300 DCHECK(is_uint12(offset)); | 4280 DCHECK(is_uint12(offset)); |
4301 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); | 4281 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); |
4302 } | 4282 } |
4303 } | 4283 } |
4304 | 4284 |
4305 | 4285 |
4306 } // namespace internal | 4286 } // namespace internal |
4307 } // namespace v8 | 4287 } // namespace v8 |
4308 | 4288 |
4309 #endif // V8_TARGET_ARCH_ARM | 4289 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |