Index: src/x64/macro-assembler-x64.cc |
=================================================================== |
--- src/x64/macro-assembler-x64.cc (revision 3430) |
+++ src/x64/macro-assembler-x64.cc (working copy) |
@@ -310,6 +310,12 @@ |
} |
+void MacroAssembler::TailCallStub(CodeStub* stub) { |
+ ASSERT(allow_stub_calls()); // calls are not allowed in some stubs |
+ Jump(stub->GetCode(), RelocInfo::CODE_TARGET); |
+} |
+ |
+ |
void MacroAssembler::StubReturn(int argc) { |
ASSERT(argc >= 1 && generating_stub()); |
ret((argc - 1) * kPointerSize); |
@@ -2244,6 +2250,108 @@ |
} |
+void MacroAssembler::AllocateTwoByteString(Register result, |
+ Register length, |
+ Register scratch1, |
+ Register scratch2, |
+ Register scratch3, |
+ Label* gc_required) { |
+ // Calculate the number of bytes needed for the characters in the string while |
+ // observing object alignment. |
+ ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
+ ASSERT(kShortSize == 2); |
+ // scratch1 = length * 2 + kObjectAlignmentMask. |
+ lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask)); |
+ and_(scratch1, Immediate(~kObjectAlignmentMask)); |
+ |
+ // Allocate two byte string in new space. |
+ AllocateInNewSpace(SeqTwoByteString::kHeaderSize, |
+ times_1, |
+ scratch1, |
+ result, |
+ scratch2, |
+ scratch3, |
+ gc_required, |
+ TAG_OBJECT); |
+ |
+ // Set the map, length and hash field. |
+ LoadRoot(kScratchRegister, Heap::kStringMapRootIndex); |
+ movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
+ movl(FieldOperand(result, String::kLengthOffset), length); |
+ movl(FieldOperand(result, String::kHashFieldOffset), |
+ Immediate(String::kEmptyHashField)); |
+} |
+ |
+ |
+void MacroAssembler::AllocateAsciiString(Register result, |
+ Register length, |
+ Register scratch1, |
+ Register scratch2, |
+ Register scratch3, |
+ Label* gc_required) { |
+ // Calculate the number of bytes needed for the characters in the string while |
+ // observing object alignment. |
+ ASSERT((SeqAsciiString::kHeaderSize & kObjectAlignmentMask) == 0); |
+ movl(scratch1, length); |
+ ASSERT(kCharSize == 1); |
+ addq(scratch1, Immediate(kObjectAlignmentMask)); |
+ and_(scratch1, Immediate(~kObjectAlignmentMask)); |
+ |
+ // Allocate ascii string in new space. |
+ AllocateInNewSpace(SeqAsciiString::kHeaderSize, |
+ times_1, |
+ scratch1, |
+ result, |
+ scratch2, |
+ scratch3, |
+ gc_required, |
+ TAG_OBJECT); |
+ |
+ // Set the map, length and hash field. |
+ LoadRoot(kScratchRegister, Heap::kAsciiStringMapRootIndex); |
+ movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
+ movl(FieldOperand(result, String::kLengthOffset), length); |
+ movl(FieldOperand(result, String::kHashFieldOffset), |
+ Immediate(String::kEmptyHashField)); |
+} |
+ |
+ |
+void MacroAssembler::AllocateConsString(Register result, |
+ Register scratch1, |
+ Register scratch2, |
+ Label* gc_required) { |
+ // Allocate heap number in new space. |
+ AllocateInNewSpace(ConsString::kSize, |
+ result, |
+ scratch1, |
+ scratch2, |
+ gc_required, |
+ TAG_OBJECT); |
+ |
+ // Set the map. The other fields are left uninitialized. |
+ LoadRoot(kScratchRegister, Heap::kConsStringMapRootIndex); |
+ movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
+} |
+ |
+ |
+void MacroAssembler::AllocateAsciiConsString(Register result, |
+ Register scratch1, |
+ Register scratch2, |
+ Label* gc_required) { |
+ // Allocate heap number in new space. |
+ AllocateInNewSpace(ConsString::kSize, |
+ result, |
+ scratch1, |
+ scratch2, |
+ gc_required, |
+ TAG_OBJECT); |
+ |
+ // Set the map. The other fields are left uninitialized. |
+ LoadRoot(kScratchRegister, Heap::kConsAsciiStringMapRootIndex); |
+ movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
+} |
+ |
+ |
void MacroAssembler::LoadContext(Register dst, int context_chain_length) { |
if (context_chain_length > 0) { |
// Move up the chain of contexts to the context containing the slot. |