Chromium Code Reviews| Index: src/a64/assembler-a64.cc |
| diff --git a/src/a64/assembler-a64.cc b/src/a64/assembler-a64.cc |
| index 14f78a09c7a9279ed4e9ea1cdb11bccd3c75f5c4..1f45bfffe680513da11b0310a13e73b0d44a8e80 100644 |
| --- a/src/a64/assembler-a64.cc |
| +++ b/src/a64/assembler-a64.cc |
| @@ -624,6 +624,13 @@ void Assembler::ConstantPoolMarker(uint32_t size) { |
| } |
| +void Assembler::EmitPoolGuard() { |
| + // We must generate only one instruction as this is used in scopes that |
| + // control the size of the code generated. |
| + Emit(BLR | Rn(xzr)); |
| +} |
| + |
| + |
| void Assembler::ConstantPoolGuard() { |
| #ifdef DEBUG |
| // Currently this is only used after a constant pool marker. |
| @@ -632,9 +639,7 @@ void Assembler::ConstantPoolGuard() { |
| ASSERT(instr->preceding()->IsLdrLiteralX() && |
| instr->preceding()->Rt() == xzr.code()); |
| #endif |
| - |
| - // We must generate only one instruction. |
| - Emit(BLR | Rn(xzr)); |
| + EmitPoolGuard(); |
| } |
| @@ -2427,13 +2432,15 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { |
| RelocInfo rinfo(reinterpret_cast<byte*>(pc_), rmode, data, NULL); |
| if (((rmode >= RelocInfo::JS_RETURN) && |
| (rmode <= RelocInfo::DEBUG_BREAK_SLOT)) || |
| - (rmode == RelocInfo::CONST_POOL)) { |
| + (rmode == RelocInfo::CONST_POOL) || |
| + (rmode == RelocInfo::VENEER_POOL)) { |
| // Adjust code for new modes. |
| ASSERT(RelocInfo::IsDebugBreakSlot(rmode) |
| || RelocInfo::IsJSReturn(rmode) |
| || RelocInfo::IsComment(rmode) |
| || RelocInfo::IsPosition(rmode) |
| - || RelocInfo::IsConstPool(rmode)); |
| + || RelocInfo::IsConstPool(rmode) |
| + || RelocInfo::IsVeneerPool(rmode)); |
| // These modes do not need an entry in the constant pool. |
| } else { |
| ASSERT(num_pending_reloc_info_ < kMaxNumPendingRelocInfo); |
| @@ -2570,7 +2577,8 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) { |
| ASSERT(rinfo.rmode() != RelocInfo::COMMENT && |
| rinfo.rmode() != RelocInfo::POSITION && |
| rinfo.rmode() != RelocInfo::STATEMENT_POSITION && |
| - rinfo.rmode() != RelocInfo::CONST_POOL); |
| + rinfo.rmode() != RelocInfo::CONST_POOL && |
| + rinfo.rmode() != RelocInfo::VENEER_POOL); |
| Instruction* instr = reinterpret_cast<Instruction*>(rinfo.pc()); |
| // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0. |
| @@ -2612,6 +2620,18 @@ void Assembler::EmitVeneers(bool need_protection, int margin) { |
| BlockPoolsScope scope(this); |
| RecordComment("[ Veneers"); |
| + // The exact size of the veneer pool must be recorded (see the comment at the |
| + // declaration site of RecordConstPool()), but computing the number of |
| + // veneers that will be generated is not obvious. So instead we remember the |
| + // current position and will record the size after the pool has been |
| + // generated. |
| + Label size_check; |
| + bind(&size_check); |
| + int veneer_pool_relocinfo_loc = pc_offset(); |
| +#ifdef DEBUG |
| + byte* reloc_writer_record_pos = reloc_info_writer.pos(); |
| +#endif |
| + |
| Label end; |
| if (need_protection) { |
| b(&end); |
| @@ -2619,7 +2639,7 @@ void Assembler::EmitVeneers(bool need_protection, int margin) { |
| EmitVeneersGuard(); |
| - Label size_check; |
| + Label veneer_size_check; |
| std::multimap<int, FarBranchInfo>::iterator it, it_to_delete; |
| @@ -2630,7 +2650,7 @@ void Assembler::EmitVeneers(bool need_protection, int margin) { |
| Label* label = it->second.label_; |
| #ifdef DEBUG |
| - bind(&size_check); |
| + bind(&veneer_size_check); |
| #endif |
| // Patch the branch to point to the current position, and emit a branch |
| // to the label. |
| @@ -2639,9 +2659,9 @@ void Assembler::EmitVeneers(bool need_protection, int margin) { |
| branch->SetImmPCOffsetTarget(veneer); |
| b(label); |
| #ifdef DEBUG |
| - ASSERT(SizeOfCodeGeneratedSince(&size_check) <= |
| + ASSERT(SizeOfCodeGeneratedSince(&veneer_size_check) <= |
| static_cast<uint64_t>(kMaxVeneerCodeSize)); |
| - size_check.Unuse(); |
| + veneer_size_check.Unuse(); |
| #endif |
| it_to_delete = it++; |
| @@ -2651,6 +2671,14 @@ void Assembler::EmitVeneers(bool need_protection, int margin) { |
| } |
| } |
| + // Record the veneer pool size. |
| + ASSERT(reloc_writer_record_pos == reloc_info_writer.pos()); |
| + int pool_size = SizeOfCodeGeneratedSince(&size_check); |
| + RelocInfo rinfo(buffer_ + veneer_pool_relocinfo_loc, |
| + RelocInfo::VENEER_POOL, static_cast<intptr_t>(pool_size), |
|
ulan
2014/03/07 10:51:57
Are there test checking that we read the size corr
|
| + NULL); |
| + reloc_info_writer.Write(&rinfo); |
| + |
| if (unresolved_branches_.empty()) { |
| next_veneer_pool_check_ = kMaxInt; |
| } else { |
| @@ -2664,13 +2692,6 @@ void Assembler::EmitVeneers(bool need_protection, int margin) { |
| } |
| -void Assembler::EmitVeneersGuard() { |
| - if (emit_debug_code()) { |
| - Unreachable(); |
| - } |
| -} |
| - |
| - |
| void Assembler::CheckVeneerPool(bool require_jump, |
| int margin) { |
| // There is nothing to do if there are no pending veneer pool entries. |