MIPS: Make TestJSArrayForAllocationMemento less awkward.

Port r17220 (be968d52)

Original commit message:
Generated code ended up having two conditional jump statements in a
row. Also introduce JumpIfJSArrayHasAllocationMemento which handles
most cases more simply.

BUG=
R=gergely@homejinni.com

Review URL: https://codereview.chromium.org/27421002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17225 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
palfia@homejinni.com 2013-10-15 23:12:15 +00:00
parent 2268defb84
commit f5abb8e52a
4 changed files with 30 additions and 18 deletions

View File

@ -156,8 +156,7 @@ void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
// ----------------------------------- // -----------------------------------
if (mode == TRACK_ALLOCATION_SITE) { if (mode == TRACK_ALLOCATION_SITE) {
ASSERT(allocation_memento_found != NULL); ASSERT(allocation_memento_found != NULL);
masm->TestJSArrayForAllocationMemento(a2, t0, eq, __ JumpIfJSArrayHasAllocationMemento(a2, t0, allocation_memento_found);
allocation_memento_found);
} }
// Set transitioned map. // Set transitioned map.
@ -188,7 +187,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
Register scratch = t6; Register scratch = t6;
if (mode == TRACK_ALLOCATION_SITE) { if (mode == TRACK_ALLOCATION_SITE) {
masm->TestJSArrayForAllocationMemento(a2, t0, eq, fail); __ JumpIfJSArrayHasAllocationMemento(a2, t0, fail);
} }
// Check for empty arrays, which only require a map transition and no changes // Check for empty arrays, which only require a map transition and no changes
@ -316,7 +315,7 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
Label entry, loop, convert_hole, gc_required, only_change_map; Label entry, loop, convert_hole, gc_required, only_change_map;
if (mode == TRACK_ALLOCATION_SITE) { if (mode == TRACK_ALLOCATION_SITE) {
masm->TestJSArrayForAllocationMemento(a2, t0, eq, fail); __ JumpIfJSArrayHasAllocationMemento(a2, t0, fail);
} }
// Check for empty arrays, which only require a map transition and no changes // Check for empty arrays, which only require a map transition and no changes

View File

@ -4466,10 +4466,11 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
Register object = ToRegister(instr->object()); Register object = ToRegister(instr->object());
Register temp = ToRegister(instr->temp()); Register temp = ToRegister(instr->temp());
Label fail; Label no_memento_found;
__ TestJSArrayForAllocationMemento(object, temp, ne, &fail); __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found,
ne, &no_memento_found);
DeoptimizeIf(al, instr->environment()); DeoptimizeIf(al, instr->environment());
__ bind(&fail); __ bind(&no_memento_found);
} }

View File

@ -5570,23 +5570,24 @@ void MacroAssembler::ClampDoubleToUint8(Register result_reg,
void MacroAssembler::TestJSArrayForAllocationMemento( void MacroAssembler::TestJSArrayForAllocationMemento(
Register receiver_reg, Register receiver_reg,
Register scratch_reg, Register scratch_reg,
Label* no_memento_found,
Condition cond, Condition cond,
Label* allocation_memento_present) { Label* allocation_memento_present) {
Label no_memento_available;
ExternalReference new_space_start = ExternalReference new_space_start =
ExternalReference::new_space_start(isolate()); ExternalReference::new_space_start(isolate());
ExternalReference new_space_allocation_top = ExternalReference new_space_allocation_top =
ExternalReference::new_space_allocation_top_address(isolate()); ExternalReference::new_space_allocation_top_address(isolate());
Addu(scratch_reg, receiver_reg, Addu(scratch_reg, receiver_reg,
Operand(JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag)); Operand(JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag));
Branch(&no_memento_available, lt, scratch_reg, Operand(new_space_start)); Branch(no_memento_found, lt, scratch_reg, Operand(new_space_start));
li(at, Operand(new_space_allocation_top)); li(at, Operand(new_space_allocation_top));
lw(at, MemOperand(at)); lw(at, MemOperand(at));
Branch(&no_memento_available, gt, scratch_reg, Operand(at)); Branch(no_memento_found, gt, scratch_reg, Operand(at));
lw(scratch_reg, MemOperand(scratch_reg, -AllocationMemento::kSize)); lw(scratch_reg, MemOperand(scratch_reg, -AllocationMemento::kSize));
Branch(allocation_memento_present, cond, scratch_reg, if (allocation_memento_present) {
Operand(isolate()->factory()->allocation_memento_map())); Branch(allocation_memento_present, cond, scratch_reg,
bind(&no_memento_available); Operand(isolate()->factory()->allocation_memento_map()));
}
} }

View File

@ -1520,11 +1520,22 @@ class MacroAssembler: public Assembler {
// to another type. // to another type.
// On entry, receiver_reg should point to the array object. // On entry, receiver_reg should point to the array object.
// scratch_reg gets clobbered. // scratch_reg gets clobbered.
// If allocation info is present, jump to allocation_info_present // If allocation info is present, jump to allocation_memento_present.
void TestJSArrayForAllocationMemento(Register receiver_reg, void TestJSArrayForAllocationMemento(
Register scratch_reg, Register receiver_reg,
Condition cond, Register scratch_reg,
Label* allocation_memento_present); Label* no_memento_found,
Condition cond = al,
Label* allocation_memento_present = NULL);
void JumpIfJSArrayHasAllocationMemento(Register receiver_reg,
Register scratch_reg,
Label* memento_found) {
Label no_memento_found;
TestJSArrayForAllocationMemento(receiver_reg, scratch_reg,
&no_memento_found, eq, memento_found);
bind(&no_memento_found);
}
private: private:
void CallCFunctionHelper(Register function, void CallCFunctionHelper(Register function,