| Index: src/x64/virtual-frame-x64.cc
|
| diff --git a/src/x64/virtual-frame-x64.cc b/src/x64/virtual-frame-x64.cc
|
| index e65378dc074e8ed554e7a04d9a7cf6ee2c5fd187..f5e17fd18f5d312dbf7bc80e8c963426987bff43 100644
|
| --- a/src/x64/virtual-frame-x64.cc
|
| +++ b/src/x64/virtual-frame-x64.cc
|
| @@ -115,25 +115,45 @@ void VirtualFrame::AllocateStackSlots() {
|
| Handle<Object> undefined = Factory::undefined_value();
|
| FrameElement initial_value =
|
| FrameElement::ConstantElement(undefined, FrameElement::SYNCED);
|
| - if (count == 1) {
|
| - __ Push(undefined);
|
| - } else if (count < kLocalVarBound) {
|
| - // For less locals the unrolled loop is more compact.
|
| - __ movq(kScratchRegister, undefined, RelocInfo::EMBEDDED_OBJECT);
|
| + if (count < kLocalVarBound) {
|
| + // For fewer locals the unrolled loop is more compact.
|
| +
|
| + // Hope for one of the first eight registers, where the push operation
|
| + // takes only one byte (kScratchRegister needs the REX.W bit).
|
| + Result tmp = cgen()->allocator()->Allocate();
|
| + ASSERT(tmp.is_valid());
|
| + __ movq(tmp.reg(), undefined, RelocInfo::EMBEDDED_OBJECT);
|
| for (int i = 0; i < count; i++) {
|
| - __ push(kScratchRegister);
|
| + __ push(tmp.reg());
|
| }
|
| } else {
|
| // For more locals a loop in generated code is more compact.
|
| Label alloc_locals_loop;
|
| Result cnt = cgen()->allocator()->Allocate();
|
| ASSERT(cnt.is_valid());
|
| - __ movq(cnt.reg(), Immediate(count));
|
| __ movq(kScratchRegister, undefined, RelocInfo::EMBEDDED_OBJECT);
|
| +#ifdef DEBUG
|
| + Label loop_size;
|
| + __ bind(&loop_size);
|
| +#endif
|
| + if (is_uint8(count)) {
|
| + // Loading imm8 is shorter than loading imm32.
|
| + // Loading only partial byte register, and using decb below.
|
| + __ movb(cnt.reg(), Immediate(count));
|
| + } else {
|
| + __ movl(cnt.reg(), Immediate(count));
|
| + }
|
| __ bind(&alloc_locals_loop);
|
| __ push(kScratchRegister);
|
| - __ decl(cnt.reg());
|
| + if (is_uint8(count)) {
|
| + __ decb(cnt.reg());
|
| + } else {
|
| + __ decl(cnt.reg());
|
| + }
|
| __ j(not_zero, &alloc_locals_loop);
|
| +#ifdef DEBUG
|
| + CHECK(masm()->SizeOfCodeGeneratedSince(&loop_size) < kLocalVarBound);
|
| +#endif
|
| }
|
| for (int i = 0; i < count; i++) {
|
| elements_.Add(initial_value);
|
|
|