Make TestJSArrayForAllocationMemento less awkward.

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

R=jkummerow@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17220 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 362c0cfb
...@@ -402,8 +402,7 @@ void ElementsTransitionGenerator::GenerateMapChangeElementsTransition( ...@@ -402,8 +402,7 @@ void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
// ----------------------------------- // -----------------------------------
if (mode == TRACK_ALLOCATION_SITE) { if (mode == TRACK_ALLOCATION_SITE) {
ASSERT(allocation_memento_found != NULL); ASSERT(allocation_memento_found != NULL);
__ TestJSArrayForAllocationMemento(r2, r4); __ JumpIfJSArrayHasAllocationMemento(r2, r4, allocation_memento_found);
__ b(eq, allocation_memento_found);
} }
// Set transitioned map. // Set transitioned map.
...@@ -432,8 +431,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble( ...@@ -432,8 +431,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
Label loop, entry, convert_hole, gc_required, only_change_map, done; Label loop, entry, convert_hole, gc_required, only_change_map, done;
if (mode == TRACK_ALLOCATION_SITE) { if (mode == TRACK_ALLOCATION_SITE) {
__ TestJSArrayForAllocationMemento(r2, r4); __ JumpIfJSArrayHasAllocationMemento(r2, r4, fail);
__ b(eq, 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
...@@ -559,8 +557,7 @@ void ElementsTransitionGenerator::GenerateDoubleToObject( ...@@ -559,8 +557,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) {
__ TestJSArrayForAllocationMemento(r2, r4); __ JumpIfJSArrayHasAllocationMemento(r2, r4, fail);
__ b(eq, 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
......
...@@ -4536,8 +4536,10 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { ...@@ -4536,8 +4536,10 @@ 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());
__ TestJSArrayForAllocationMemento(object, temp); Label no_memento_found;
__ TestJSArrayForAllocationMemento(object, temp, &no_memento_found);
DeoptimizeIf(eq, instr->environment()); DeoptimizeIf(eq, instr->environment());
__ bind(&no_memento_found);
} }
......
...@@ -3858,8 +3858,8 @@ void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) { ...@@ -3858,8 +3858,8 @@ void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) {
void MacroAssembler::TestJSArrayForAllocationMemento( void MacroAssembler::TestJSArrayForAllocationMemento(
Register receiver_reg, Register receiver_reg,
Register scratch_reg) { Register scratch_reg,
Label no_memento_available; Label* no_memento_found) {
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 =
...@@ -3867,15 +3867,14 @@ void MacroAssembler::TestJSArrayForAllocationMemento( ...@@ -3867,15 +3867,14 @@ void MacroAssembler::TestJSArrayForAllocationMemento(
add(scratch_reg, receiver_reg, add(scratch_reg, receiver_reg,
Operand(JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag)); Operand(JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag));
cmp(scratch_reg, Operand(new_space_start)); cmp(scratch_reg, Operand(new_space_start));
b(lt, &no_memento_available); b(lt, no_memento_found);
mov(ip, Operand(new_space_allocation_top)); mov(ip, Operand(new_space_allocation_top));
ldr(ip, MemOperand(ip)); ldr(ip, MemOperand(ip));
cmp(scratch_reg, ip); cmp(scratch_reg, ip);
b(gt, &no_memento_available); b(gt, no_memento_found);
ldr(scratch_reg, MemOperand(scratch_reg, -AllocationMemento::kSize)); ldr(scratch_reg, MemOperand(scratch_reg, -AllocationMemento::kSize));
cmp(scratch_reg, cmp(scratch_reg,
Operand(isolate()->factory()->allocation_memento_map())); Operand(isolate()->factory()->allocation_memento_map()));
bind(&no_memento_available);
} }
......
...@@ -1388,9 +1388,20 @@ class MacroAssembler: public Assembler { ...@@ -1388,9 +1388,20 @@ 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, condition flags are set to eq // If allocation info is present, condition flags are set to eq.
void TestJSArrayForAllocationMemento(Register receiver_reg, void TestJSArrayForAllocationMemento(Register receiver_reg,
Register scratch_reg); Register scratch_reg,
Label* no_memento_found);
void JumpIfJSArrayHasAllocationMemento(Register receiver_reg,
Register scratch_reg,
Label* memento_found) {
Label no_memento_found;
TestJSArrayForAllocationMemento(receiver_reg, scratch_reg,
&no_memento_found);
b(eq, memento_found);
bind(&no_memento_found);
}
private: private:
void CallCFunctionHelper(Register function, void CallCFunctionHelper(Register function,
......
...@@ -666,8 +666,7 @@ void ElementsTransitionGenerator::GenerateMapChangeElementsTransition( ...@@ -666,8 +666,7 @@ void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
// ----------------------------------- // -----------------------------------
if (mode == TRACK_ALLOCATION_SITE) { if (mode == TRACK_ALLOCATION_SITE) {
ASSERT(allocation_memento_found != NULL); ASSERT(allocation_memento_found != NULL);
__ TestJSArrayForAllocationMemento(edx, edi); __ JumpIfJSArrayHasAllocationMemento(edx, edi, allocation_memento_found);
__ j(equal, allocation_memento_found);
} }
// Set transitioned map. // Set transitioned map.
...@@ -694,8 +693,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble( ...@@ -694,8 +693,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
Label loop, entry, convert_hole, gc_required, only_change_map; Label loop, entry, convert_hole, gc_required, only_change_map;
if (mode == TRACK_ALLOCATION_SITE) { if (mode == TRACK_ALLOCATION_SITE) {
__ TestJSArrayForAllocationMemento(edx, edi); __ JumpIfJSArrayHasAllocationMemento(edx, edi, fail);
__ j(equal, 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
...@@ -833,8 +831,7 @@ void ElementsTransitionGenerator::GenerateDoubleToObject( ...@@ -833,8 +831,7 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
Label loop, entry, convert_hole, gc_required, only_change_map, success; Label loop, entry, convert_hole, gc_required, only_change_map, success;
if (mode == TRACK_ALLOCATION_SITE) { if (mode == TRACK_ALLOCATION_SITE) {
__ TestJSArrayForAllocationMemento(edx, edi); __ JumpIfJSArrayHasAllocationMemento(edx, edi, fail);
__ j(equal, 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
......
...@@ -4813,8 +4813,10 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { ...@@ -4813,8 +4813,10 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* 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());
__ TestJSArrayForAllocationMemento(object, temp); Label no_memento_found;
__ TestJSArrayForAllocationMemento(object, temp, &no_memento_found);
DeoptimizeIf(equal, instr->environment()); DeoptimizeIf(equal, instr->environment());
__ bind(&no_memento_found);
} }
......
...@@ -3512,9 +3512,8 @@ void MacroAssembler::CheckEnumCache(Label* call_runtime) { ...@@ -3512,9 +3512,8 @@ void MacroAssembler::CheckEnumCache(Label* call_runtime) {
void MacroAssembler::TestJSArrayForAllocationMemento( void MacroAssembler::TestJSArrayForAllocationMemento(
Register receiver_reg, Register receiver_reg,
Register scratch_reg) { Register scratch_reg,
Label no_memento_available; Label* no_memento_found) {
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 =
...@@ -3523,12 +3522,11 @@ void MacroAssembler::TestJSArrayForAllocationMemento( ...@@ -3523,12 +3522,11 @@ void MacroAssembler::TestJSArrayForAllocationMemento(
lea(scratch_reg, Operand(receiver_reg, lea(scratch_reg, Operand(receiver_reg,
JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag)); JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag));
cmp(scratch_reg, Immediate(new_space_start)); cmp(scratch_reg, Immediate(new_space_start));
j(less, &no_memento_available); j(less, no_memento_found);
cmp(scratch_reg, Operand::StaticVariable(new_space_allocation_top)); cmp(scratch_reg, Operand::StaticVariable(new_space_allocation_top));
j(greater, &no_memento_available); j(greater, no_memento_found);
cmp(MemOperand(scratch_reg, -AllocationMemento::kSize), cmp(MemOperand(scratch_reg, -AllocationMemento::kSize),
Immediate(isolate()->factory()->allocation_memento_map())); Immediate(isolate()->factory()->allocation_memento_map()));
bind(&no_memento_available);
} }
......
...@@ -957,9 +957,20 @@ class MacroAssembler: public Assembler { ...@@ -957,9 +957,20 @@ 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, conditional code is set to equal // If allocation info is present, conditional code is set to equal.
void TestJSArrayForAllocationMemento(Register receiver_reg, void TestJSArrayForAllocationMemento(Register receiver_reg,
Register scratch_reg); Register scratch_reg,
Label* no_memento_found);
void JumpIfJSArrayHasAllocationMemento(Register receiver_reg,
Register scratch_reg,
Label* memento_found) {
Label no_memento_found;
TestJSArrayForAllocationMemento(receiver_reg, scratch_reg,
&no_memento_found);
j(equal, memento_found);
bind(&no_memento_found);
}
private: private:
bool generating_stub_; bool generating_stub_;
......
...@@ -263,8 +263,7 @@ void ElementsTransitionGenerator::GenerateMapChangeElementsTransition( ...@@ -263,8 +263,7 @@ void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
// ----------------------------------- // -----------------------------------
if (mode == TRACK_ALLOCATION_SITE) { if (mode == TRACK_ALLOCATION_SITE) {
ASSERT(allocation_memento_found != NULL); ASSERT(allocation_memento_found != NULL);
__ TestJSArrayForAllocationMemento(rdx, rdi); __ JumpIfJSArrayHasAllocationMemento(rdx, rdi, allocation_memento_found);
__ j(equal, allocation_memento_found);
} }
// Set transitioned map. // Set transitioned map.
...@@ -292,8 +291,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble( ...@@ -292,8 +291,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
Label allocated, new_backing_store, only_change_map, done; Label allocated, new_backing_store, only_change_map, done;
if (mode == TRACK_ALLOCATION_SITE) { if (mode == TRACK_ALLOCATION_SITE) {
__ TestJSArrayForAllocationMemento(rdx, rdi); __ JumpIfJSArrayHasAllocationMemento(rdx, rdi, fail);
__ j(equal, 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
...@@ -418,8 +416,7 @@ void ElementsTransitionGenerator::GenerateDoubleToObject( ...@@ -418,8 +416,7 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
Label loop, entry, convert_hole, gc_required, only_change_map; Label loop, entry, convert_hole, gc_required, only_change_map;
if (mode == TRACK_ALLOCATION_SITE) { if (mode == TRACK_ALLOCATION_SITE) {
__ TestJSArrayForAllocationMemento(rdx, rdi); __ JumpIfJSArrayHasAllocationMemento(rdx, rdi, fail);
__ j(equal, 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
......
...@@ -4257,8 +4257,10 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { ...@@ -4257,8 +4257,10 @@ 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());
__ TestJSArrayForAllocationMemento(object, temp); Label no_memento_found;
__ TestJSArrayForAllocationMemento(object, temp, &no_memento_found);
DeoptimizeIf(equal, instr->environment()); DeoptimizeIf(equal, instr->environment());
__ bind(&no_memento_found);
} }
......
...@@ -4921,8 +4921,8 @@ void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) { ...@@ -4921,8 +4921,8 @@ void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) {
void MacroAssembler::TestJSArrayForAllocationMemento( void MacroAssembler::TestJSArrayForAllocationMemento(
Register receiver_reg, Register receiver_reg,
Register scratch_reg) { Register scratch_reg,
Label no_memento_available; Label* no_memento_found) {
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 =
...@@ -4932,12 +4932,11 @@ void MacroAssembler::TestJSArrayForAllocationMemento( ...@@ -4932,12 +4932,11 @@ void MacroAssembler::TestJSArrayForAllocationMemento(
JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag)); JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag));
movq(kScratchRegister, new_space_start); movq(kScratchRegister, new_space_start);
cmpq(scratch_reg, kScratchRegister); cmpq(scratch_reg, kScratchRegister);
j(less, &no_memento_available); j(less, no_memento_found);
cmpq(scratch_reg, ExternalOperand(new_space_allocation_top)); cmpq(scratch_reg, ExternalOperand(new_space_allocation_top));
j(greater, &no_memento_available); j(greater, no_memento_found);
CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize), CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize),
Heap::kAllocationMementoMapRootIndex); Heap::kAllocationMementoMapRootIndex);
bind(&no_memento_available);
} }
......
...@@ -1412,9 +1412,20 @@ class MacroAssembler: public Assembler { ...@@ -1412,9 +1412,20 @@ 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, condition flags are set to equal // If allocation info is present, condition flags are set to equal.
void TestJSArrayForAllocationMemento(Register receiver_reg, void TestJSArrayForAllocationMemento(Register receiver_reg,
Register scratch_reg); Register scratch_reg,
Label* no_memento_found);
void JumpIfJSArrayHasAllocationMemento(Register receiver_reg,
Register scratch_reg,
Label* memento_found) {
Label no_memento_found;
TestJSArrayForAllocationMemento(receiver_reg, scratch_reg,
&no_memento_found);
j(equal, memento_found);
bind(&no_memento_found);
}
private: private:
// Order general registers are pushed by Pushad. // Order general registers are pushed by Pushad.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment