return GeneratePrologue() &&
GenerateBody() &&
GenerateDeferredCode() &&
+ GenerateJumpTable() &&
GenerateSafepointTable();
}
}
+bool LCodeGen::GenerateJumpTable() {
+ for (int i = 0; i < jump_table_.length(); i++) {
+ JumpTableEntry* info = jump_table_[i];
+ __ bind(&(info->label_));
+ __ Jump(info->address_, RelocInfo::RUNTIME_ENTRY);
+ }
+ return !is_aborted();
+}
+
+
bool LCodeGen::GenerateDeferredCode() {
ASSERT(is_generating());
for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
if (cc == no_condition) {
__ Jump(entry, RelocInfo::RUNTIME_ENTRY);
} else {
- NearLabel done;
- __ j(NegateCondition(cc), &done);
- __ Jump(entry, RelocInfo::RUNTIME_ENTRY);
- __ bind(&done);
+ JumpTableEntry* jump_info = NULL;
+ // We often have several deopts to the same entry, reuse the last
+ // jump entry if this is the case.
+ if (jump_table_.length() > 0 &&
+ jump_table_[jump_table_.length() - 1]->address_ == entry) {
+ jump_info = jump_table_[jump_table_.length() - 1];
+ } else {
+ jump_info = new JumpTableEntry(entry);
+ jump_table_.Add(jump_info);
+ }
+ __ j(cc, &jump_info->label_);
}
}
current_instruction_(-1),
instructions_(chunk->instructions()),
deoptimizations_(4),
+ jump_table_(4),
deoptimization_literals_(8),
inlined_function_count_(0),
scope_(chunk->graph()->info()->scope()),
bool GeneratePrologue();
bool GenerateBody();
bool GenerateDeferredCode();
+ bool GenerateJumpTable();
bool GenerateSafepointTable();
void CallCode(Handle<Code> code,
// Emits code for pushing a constant operand.
void EmitPushConstantOperand(LOperand* operand);
+ struct JumpTableEntry {
+ inline JumpTableEntry(Address address)
+ : label_(),
+ address_(address) { }
+ Label label_;
+ Address address_;
+ };
+
LChunk* const chunk_;
MacroAssembler* const masm_;
CompilationInfo* const info_;
int current_instruction_;
const ZoneList<LInstruction*>* instructions_;
ZoneList<LEnvironment*> deoptimizations_;
+ ZoneList<JumpTableEntry*> jump_table_;
ZoneList<Handle<Object> > deoptimization_literals_;
int inlined_function_count_;
Scope* const scope_;