Index: runtime/vm/intrinsifier_x64.cc |
=================================================================== |
--- runtime/vm/intrinsifier_x64.cc (revision 7950) |
+++ runtime/vm/intrinsifier_x64.cc (working copy) |
@@ -7,19 +7,35 @@ |
#include "vm/intrinsifier.h" |
+#include "vm/assembler.h" |
+#include "vm/instructions.h" |
+ |
namespace dart { |
+ |
+DECLARE_FLAG(bool, enable_type_checks); |
+ |
+// When entering intrinsics code: |
+// RBX: IC Data |
+// R10: Arguments descriptor |
+// TOS: Return address |
+ |
+#define __ assembler-> |
+ |
bool Intrinsifier::ObjectArray_Allocate(Assembler* assembler) { |
return false; |
} |
bool Intrinsifier::Array_getLength(Assembler* assembler) { |
- return false; |
+ __ movq(RAX, Address(RSP, + 1 * kWordSize)); |
+ __ movq(RAX, FieldAddress(RAX, Array::length_offset())); |
+ __ ret(); |
+ return true; |
} |
bool Intrinsifier::ImmutableArray_getLength(Assembler* assembler) { |
- return false; |
+ return Array_getLength(assembler); |
} |
@@ -29,7 +45,7 @@ |
bool Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) { |
- return false; |
+ return Array_getIndexed(assembler); |
} |
@@ -43,13 +59,22 @@ |
} |
+// Get length of growable object array. |
+// On stack: growable array (+1), return-address (+0). |
bool Intrinsifier::GrowableArray_getLength(Assembler* assembler) { |
- return false; |
+ __ movq(RAX, Address(RSP, + 1 * kWordSize)); |
+ __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::length_offset())); |
+ __ ret(); |
+ return true; |
} |
bool Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) { |
- return false; |
+ __ movq(RAX, Address(RSP, + 1 * kWordSize)); |
+ __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); |
+ __ movq(RAX, FieldAddress(RAX, Array::length_offset())); |
+ __ ret(); |
+ return true; |
} |
@@ -68,8 +93,17 @@ |
} |
+// Set data of growable object array. |
+// On stack: growable array (+2), data (+1), return-address (+0). |
bool Intrinsifier::GrowableArray_setData(Assembler* assembler) { |
- return false; |
+ if (FLAG_enable_type_checks) { |
+ return false; |
+ } |
+ __ movq(RAX, Address(RSP, + 2 * kWordSize)); |
+ __ movq(RBX, Address(RSP, + 1 * kWordSize)); |
+ __ movq(FieldAddress(RAX, GrowableObjectArray::data_offset()), RBX); |
+ __ ret(); |
+ return true; |
} |
@@ -225,7 +259,12 @@ |
bool Intrinsifier::Double_toDouble(Assembler* assembler) { |
- return false; |
+ __ movq(RAX, Address(RSP, + 1 * kWordSize)); |
+ __ ret(); |
+ // Generate enough code to satisfy patchability constraint. |
+ intptr_t offset = __ CodeSize(); |
+ __ nop(JumpPattern::InstructionLength() - offset); |
+ return true; |
} |
bool Intrinsifier::Double_add(Assembler* assembler) { |
@@ -259,7 +298,19 @@ |
bool Intrinsifier::Double_isNaN(Assembler* assembler) { |
- return false; |
+ const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
+ const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
+ Label is_true; |
+ __ movq(RAX, Address(RSP, +1 * kWordSize)); |
+ __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); |
+ __ comisd(XMM0, XMM0); |
+ __ j(PARITY_EVEN, &is_true, Assembler::kNearJump); // NaN -> true; |
+ __ LoadObject(RAX, bool_false); |
+ __ ret(); |
+ __ Bind(&is_true); |
+ __ LoadObject(RAX, bool_true); |
+ __ ret(); |
+ return true; // Method is complete, no slow case. |
} |
@@ -317,6 +368,8 @@ |
return false; |
} |
+#undef __ |
+ |
} // namespace dart |
#endif // defined TARGET_ARCH_X64 |