Index: runtime/vm/assembler_x64.cc |
=================================================================== |
--- runtime/vm/assembler_x64.cc (revision 19430) |
+++ runtime/vm/assembler_x64.cc (working copy) |
@@ -15,6 +15,7 @@ |
DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available"); |
+DECLARE_FLAG(bool, inline_alloc); |
bool CPUFeatures::sse4_1_supported_ = false; |
@@ -2218,6 +2219,61 @@ |
} |
+void Assembler::EnterDartFrame(intptr_t frame_size) { |
+ const intptr_t offset = CodeSize(); |
+ EnterFrame(0); |
+ Label dart_entry; |
+ call(&dart_entry); |
+ Bind(&dart_entry); |
+ // Adjust saved PC for any intrinsic code that could have been generated |
+ // before a frame is created. |
+ if (offset != 0) { |
+ addq(Address(RSP, 0), Immediate(-offset)); |
+ } |
+ if (frame_size != 0) { |
+ subq(RSP, Immediate(frame_size)); |
+ } |
+} |
+ |
+ |
+void Assembler::EnterStubFrame() { |
+ EnterFrame(0); |
+ pushq(Immediate(0)); // Push 0 in the saved PC area for stub frames. |
+} |
+ |
+ |
+void Assembler::TryAllocate(const Class& cls, |
+ Label* failure, |
+ bool near_jump, |
+ Register instance_reg) { |
+ ASSERT(failure != NULL); |
+ if (FLAG_inline_alloc) { |
+ Heap* heap = Isolate::Current()->heap(); |
+ const intptr_t instance_size = cls.instance_size(); |
+ movq(TMP, Immediate(heap->TopAddress())); |
+ movq(instance_reg, Address(TMP, 0)); |
+ addq(instance_reg, Immediate(instance_size)); |
+ // instance_reg: potential next object start. |
+ movq(TMP, Immediate(heap->EndAddress())); |
+ cmpq(instance_reg, Address(TMP, 0)); |
+ j(ABOVE_EQUAL, failure, near_jump); |
+ // Successfully allocated the object, now update top to point to |
+ // next object start and store the class in the class field of object. |
+ movq(TMP, Immediate(heap->TopAddress())); |
+ movq(Address(TMP, 0), instance_reg); |
+ ASSERT(instance_size >= kHeapObjectTag); |
+ subq(instance_reg, Immediate(instance_size - kHeapObjectTag)); |
+ uword tags = 0; |
+ tags = RawObject::SizeTag::update(instance_size, tags); |
+ ASSERT(cls.id() != kIllegalCid); |
+ tags = RawObject::ClassIdTag::update(cls.id(), tags); |
+ movq(FieldAddress(instance_reg, Object::tags_offset()), Immediate(tags)); |
+ } else { |
+ jmp(failure); |
+ } |
+} |
+ |
+ |
void Assembler::Align(int alignment, int offset) { |
ASSERT(Utils::IsPowerOfTwo(alignment)); |
int pos = offset + buffer_.GetPosition(); |