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

Unified Diff: src/mips/assembler-mips.h

Issue 7239020: MIPS: Long branch implementation and trampoline improvement. (Closed)
Patch Set: Update per comments, refactor buffer-growth-blocking for internal refs. Created 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/mips/assembler-mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mips/assembler-mips.h
diff --git a/src/mips/assembler-mips.h b/src/mips/assembler-mips.h
index aeecee616bc9ebcd71568416ebaf36b106ce94e9..92c958b9620d605db52731b03b4e8a6a2a6f62e0 100644
--- a/src/mips/assembler-mips.h
+++ b/src/mips/assembler-mips.h
@@ -481,6 +481,9 @@ class Assembler : public AssemblerBase {
// Note: The same Label can be used for forward and backward branches
// but it may be bound only once.
void bind(Label* L); // Binds an unbound label L to current code position.
+ // Determines if Label is bound and near enough so that branch instruction
+ // can be used to reach it, instead of jump instruction.
+ bool is_near(Label* L);
// Returns the branch offset to the given label from the current code
// position. Links the label to the current position if it is still unbound.
@@ -491,6 +494,7 @@ class Assembler : public AssemblerBase {
ASSERT((o & 3) == 0); // Assert the offset is aligned.
return o >> 2;
}
+ uint32_t jump_address(Label* L);
// Puts a labels target address at the given position.
// The high 8 bits are set to zero.
@@ -795,6 +799,25 @@ class Assembler : public AssemblerBase {
DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope);
};
+ // Class for postponing the assembly buffer growth. Typically used for
+ // sequences of instructions that must be emitted as a unit, before
+ // buffer growth (and relocation) can occur.
+ // This blocking scope is not nestable.
+ class BlockGrowBufferScope {
+ public:
+ explicit BlockGrowBufferScope(Assembler* assem) : assem_(assem) {
+ assem_->StartBlockGrowBuffer();
+ }
+ ~BlockGrowBufferScope() {
+ assem_->EndBlockGrowBuffer();
+ }
+
+ private:
+ Assembler* assem_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(BlockGrowBufferScope);
+ };
+
// Debugging.
// Mark address of the ExitJSFrame code.
@@ -811,6 +834,8 @@ class Assembler : public AssemblerBase {
// Use --code-comments to enable.
void RecordComment(const char* msg);
+ static int RelocateInternalReference(byte* pc, intptr_t pc_delta);
+
// Writes a single byte or word of data in the code stream. Used for
// inline tables, e.g., jump-tables.
void db(uint8_t data);
@@ -847,6 +872,11 @@ class Assembler : public AssemblerBase {
static bool IsBeq(Instr instr);
static bool IsBne(Instr instr);
+ static bool IsJump(Instr instr);
+ static bool IsJ(Instr instr);
+ static bool IsLui(Instr instr);
+ static bool IsOri(Instr instr);
+
static bool IsNop(Instr instr, unsigned int type);
static bool IsPop(Instr instr);
static bool IsPush(Instr instr);
@@ -868,6 +898,8 @@ class Assembler : public AssemblerBase {
static uint32_t GetSa(Instr instr);
static uint32_t GetSaField(Instr instr);
static uint32_t GetOpcodeField(Instr instr);
+ static uint32_t GetFunction(Instr instr);
+ static uint32_t GetFunctionField(Instr instr);
static uint32_t GetImmediate16(Instr instr);
static uint32_t GetLabelConst(Instr instr);
@@ -883,7 +915,7 @@ class Assembler : public AssemblerBase {
static bool IsAndImmediate(Instr instr);
- void CheckTrampolinePool(bool force_emit = false);
+ void CheckTrampolinePool();
protected:
// Relocation for a type-recording IC has the AST id added to it. This
@@ -916,6 +948,7 @@ class Assembler : public AssemblerBase {
void StartBlockTrampolinePool() {
trampoline_pool_blocked_nesting_++;
}
+
void EndBlockTrampolinePool() {
trampoline_pool_blocked_nesting_--;
}
@@ -928,6 +961,25 @@ class Assembler : public AssemblerBase {
return internal_trampoline_exception_;
}
+ bool is_trampoline_emitted() const {
+ return trampoline_emitted_;
+ }
+
+ // Temporarily block automatic assembly buffer growth.
+ void StartBlockGrowBuffer() {
+ ASSERT(!block_buffer_growth_);
+ block_buffer_growth_ = true;
+ }
+
+ void EndBlockGrowBuffer() {
+ ASSERT(block_buffer_growth_);
+ block_buffer_growth_ = false;
+ }
+
+ bool is_buffer_growth_blocked() const {
+ return block_buffer_growth_;
+ }
+
private:
// Code buffer:
// The buffer into which code and relocation info are generated.
@@ -964,6 +1016,9 @@ class Assembler : public AssemblerBase {
// Keep track of the last emitted pool to guarantee a maximal distance.
int last_trampoline_pool_end_; // pc offset of the end of the last pool.
+ // Automatic growth of the assembly buffer may be blocked for some sequences.
+ bool block_buffer_growth_; // Block growth when true.
+
// Relocation information generation.
// Each relocation is encoded as a variable size value.
static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
@@ -1044,7 +1099,6 @@ class Assembler : public AssemblerBase {
// Labels.
void print(Label* L);
void bind_to(Label* L, int pos);
- void link_to(Label* L, Label* appendix);
void next(Label* L);
// One trampoline consists of:
@@ -1057,13 +1111,17 @@ class Assembler : public AssemblerBase {
// label_count * kInstrSize.
class Trampoline {
public:
- Trampoline(int start, int slot_count, int label_count) {
+ Trampoline() {
+ start_ = 0;
+ next_slot_ = 0;
+ free_slot_count_ = 0;
+ end_ = 0;
+ }
+ Trampoline(int start, int slot_count) {
start_ = start;
next_slot_ = start;
free_slot_count_ = slot_count;
- next_label_ = start + slot_count * 2 * kInstrSize;
- free_label_count_ = label_count;
- end_ = next_label_ + (label_count - 1) * kInstrSize;
+ end_ = start + slot_count * kTrampolineSlotsSize;
}
int start() {
return start_;
@@ -1082,41 +1140,30 @@ class Assembler : public AssemblerBase {
} else {
trampoline_slot = next_slot_;
free_slot_count_--;
- next_slot_ += 2*kInstrSize;
+ next_slot_ += kTrampolineSlotsSize;
}
return trampoline_slot;
}
- int take_label() {
- int label_pos = next_label_;
- ASSERT(free_label_count_ > 0);
- free_label_count_--;
- next_label_ += kInstrSize;
- return label_pos;
- }
-
private:
int start_;
int end_;
int next_slot_;
int free_slot_count_;
- int next_label_;
- int free_label_count_;
};
- int32_t get_label_entry(int32_t pos, bool next_pool = true);
- int32_t get_trampoline_entry(int32_t pos, bool next_pool = true);
-
- static const int kSlotsPerTrampoline = 2304;
- static const int kLabelsPerTrampoline = 8;
- static const int kTrampolineInst =
- 2 * kSlotsPerTrampoline + kLabelsPerTrampoline;
- static const int kTrampolineSize = kTrampolineInst * kInstrSize;
+ int32_t get_trampoline_entry(int32_t pos);
+ int unbound_labels_count_;
+ // If trampoline is emitted, generated code is becoming large. As this is
+ // already a slow case which can possibly break our code generation for the
+ // extreme case, we use this information to trigger different mode of
+ // branch instruction generation, where we use jump instructions rather
+ // than regular branch instructions.
+ bool trampoline_emitted_;
+ static const int kTrampolineSlotsSize = 4 * kInstrSize;
static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
- static const int kMaxDistBetweenPools =
- kMaxBranchOffset - 2 * kTrampolineSize;
static const int kInvalidSlotPos = -1;
- List<Trampoline> trampolines_;
+ Trampoline trampoline_;
bool internal_trampoline_exception_;
friend class RegExpMacroAssemblerMIPS;
« no previous file with comments | « no previous file | src/mips/assembler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698