Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: src/arm/assembler-arm.cc

Issue 2039233005: Consider reloc info mode when merging constant pool entries Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/macro-assembler-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/macro-assembler-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698