Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Unified Diff: vm/intrinsifier_ia32.cc

Issue 10012042: Wire GrowableArray to use the internal VM object. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: vm/intrinsifier_ia32.cc
===================================================================
--- vm/intrinsifier_ia32.cc (revision 6293)
+++ vm/intrinsifier_ia32.cc (working copy)
@@ -70,9 +70,13 @@
V(ObjectArray, get:length, Array_getLength) \
V(ObjectArray, [], Array_getIndexed) \
V(ObjectArray, []=, Array_setIndexed) \
+ V(GrowableObjectArray, GrowableObjectArray.fromObjectArray, GArray_Allocate) \
V(GrowableObjectArray, get:length, GrowableArray_getLength) \
+ V(GrowableObjectArray, get:capacity, GrowableArray_getCapacity) \
V(GrowableObjectArray, [], GrowableArray_getIndexed) \
V(GrowableObjectArray, []=, GrowableArray_setIndexed) \
+ V(GrowableObjectArray, _setLength, GrowableArray_setLength) \
+ V(GrowableObjectArray, set:data, GrowableArray_setData) \
V(_ByteArrayBase, get:length, ByteArrayBase_getLength) \
V(_ByteArrayBase, [], ByteArrayBase_getIndexed) \
V(ImmutableArray, [], Array_getIndexed) \
@@ -104,7 +108,7 @@
__ movl(EDI, Address(ESP, kArrayLengthOffset)); // Array Length.
// Assert that length is a Smi.
__ testl(EDI, Immediate(kSmiTagSize));
- __ j(NOT_ZERO, &fall_through);
+ __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
__ cmpl(EDI, Immediate(0));
__ j(LESS, &fall_through, Assembler::kNearJump);
intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
@@ -304,36 +308,108 @@
}
-static const char* kGrowableArrayClassName = "GrowableObjectArray";
-static const char* kGrowableArrayLengthFieldName = "_length";
-static const char* kGrowableArrayArrayFieldName = "backingArray";
+// Allocate a GrowableObjectArray using the backing array specified.
+// On stack: type argument (+2), data (+1), return-address (+0).
+static bool GArray_Allocate(Assembler* assembler) {
+ // This snippet of inlined code uses the following registers:
+ // EAX, EBX
+ // and the newly allocated object is returned in EAX.
+ const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
+ const intptr_t kArrayOffset = 1 * kWordSize;
+ Label fall_through;
-// Read the length_ instance field.
+ // Compute the size to be allocated, it is based on the array length
+ // and it computed as:
+ // RoundedAllocationSize(sizeof(RawGrowableObjectArray)) +
+ intptr_t fixed_size = GrowableObjectArray::InstanceSize();
+
+ Heap* heap = Isolate::Current()->heap();
+
+ __ movl(EAX, Address::Absolute(heap->TopAddress()));
+ __ leal(EBX, Address(EAX, fixed_size));
+
+ // Check if the allocation fits into the remaining space.
+ // EAX: potential new backing array object start.
+ // EBX: potential next object start.
+ __ cmpl(EBX, Address::Absolute(heap->EndAddress()));
+ __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
+
+ // Successfully allocated the object(s), now update top to point to
+ // next object start and initialize the object.
+ __ movl(Address::Absolute(heap->TopAddress()), EBX);
+ __ addl(EAX, Immediate(kHeapObjectTag));
+
+ // Initialize the tags.
+ // EAX: new growable array object start as a tagged pointer.
+ __ movl(FieldAddress(EAX, GrowableObjectArray::tags_offset()),
+ Immediate(RawObject::SizeTag::update(fixed_size, 0)));
+
+ // Store backing array object in growable array object.
+ __ movl(EBX, Address(ESP, kArrayOffset)); // data argument.
+ __ StoreIntoObject(EAX,
+ FieldAddress(EAX, GrowableObjectArray::data_offset()),
+ EBX);
+
+ // Store class value for the growable array object.
+ // EAX: new growable array object start as a tagged pointer.
+ __ movl(EBX, FieldAddress(CTX, Context::isolate_offset()));
+ __ movl(EBX, Address(EBX, Isolate::object_store_offset()));
+ __ movl(EBX, Address(EBX, ObjectStore::growable_object_array_class_offset()));
+ __ StoreIntoObject(EAX,
+ FieldAddress(EAX, GrowableObjectArray::class_offset()),
+ EBX);
+
+ // Store the type argument field in the growable array object.
+ __ movl(EBX, Address(ESP, kTypeArgumentsOffset)); // type argument.
+ __ StoreIntoObject(EAX,
+ FieldAddress(EAX,
+ GrowableObjectArray::type_arguments_offset()),
+ EBX);
+
+ // Set the length field in the growable array object to 0.
+ __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()),
+ Immediate(0));
+ __ ret(); // returns the newly allocated object in EAX.
+
+ __ Bind(&fall_through);
+ return false;
+}
+
+
+// Get length of growable object array.
+// On stack: growable array (+1), return-address (+0).
static bool GrowableArray_getLength(Assembler* assembler) {
- intptr_t length_offset = GetOffsetForField(kGrowableArrayClassName,
- kGrowableArrayLengthFieldName);
__ movl(EAX, Address(ESP, + 1 * kWordSize));
- __ movl(EAX, FieldAddress(EAX, length_offset));
+ __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
__ ret();
return true;
}
+// Get capacity of growable object array.
+// On stack: growable array (+1), return-address (+0).
+static bool GrowableArray_getCapacity(Assembler* assembler) {
+ __ movl(EAX, Address(ESP, + 1 * kWordSize));
+ __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset()));
+ __ movl(EAX, FieldAddress(EAX, Array::length_offset()));
+ __ ret();
+ return true;
+}
+
+
+// Access growable object array at specified index.
+// On stack: growable array (+2), index (+1), return-address (+0).
static bool GrowableArray_getIndexed(Assembler* assembler) {
- intptr_t length_offset = GetOffsetForField(kGrowableArrayClassName,
- kGrowableArrayLengthFieldName);
- intptr_t array_offset = GetOffsetForField(kGrowableArrayClassName,
- kGrowableArrayArrayFieldName);
Label fall_through;
__ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
__ movl(EAX, Address(ESP, + 2 * kWordSize)); // GrowableArray.
__ testl(EBX, Immediate(kSmiTagMask));
__ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
// Range check using _length field.
- __ cmpl(EBX, FieldAddress(EAX, length_offset));
+ __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
// Runtime throws exception.
__ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
- __ movl(EAX, FieldAddress(EAX, array_offset)); // backingArray.
+ __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data.
// Note that EBX is Smi, i.e, times 2.
ASSERT(kSmiTagShift == 1);
@@ -344,25 +420,22 @@
}
-// On stack: array (+3), index (+2), value (+1), return-address (+0).
+// Set value into growable object array at specified index.
+// On stack: growable array (+3), index (+2), value (+1), return-address (+0).
static bool GrowableArray_setIndexed(Assembler* assembler) {
if (FLAG_enable_type_checks) {
return false;
}
Label fall_through;
- intptr_t length_offset = GetOffsetForField(kGrowableArrayClassName,
- kGrowableArrayLengthFieldName);
- intptr_t array_offset = GetOffsetForField(kGrowableArrayClassName,
- kGrowableArrayArrayFieldName);
__ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index.
__ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray.
__ testl(EBX, Immediate(kSmiTagMask));
__ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
// Range check using _length field.
- __ cmpl(EBX, FieldAddress(EAX, length_offset));
+ __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
// Runtime throws exception.
__ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
- __ movl(EAX, FieldAddress(EAX, array_offset)); // backingArray.
+ __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data.
__ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value.
// Note that EBX is Smi, i.e, times 2.
ASSERT(kSmiTagShift == 1);
@@ -375,6 +448,36 @@
}
+// Set length of growable object array.
+// On stack: growable array (+2), length (+1), return-address (+0).
+static bool GrowableArray_setLength(Assembler* assembler) {
+ Label fall_through;
+ __ movl(EAX, Address(ESP, + 2 * kWordSize));
+ __ movl(EBX, Address(ESP, + 1 * kWordSize));
+ __ movl(EDI, FieldAddress(EAX, GrowableObjectArray::data_offset()));
+ __ cmpl(EBX, FieldAddress(EDI, Array::length_offset()));
+ __ j(ABOVE, &fall_through, Assembler::kNearJump);
+ __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), EBX);
+ __ ret();
+ __ Bind(&fall_through);
+ return true;
+}
+
+
+// Set data of growable object array.
+// On stack: growable array (+2), data (+1), return-address (+0).
+static bool GrowableArray_setData(Assembler* assembler) {
+ if (FLAG_enable_type_checks) {
+ return false;
+ }
+ __ movl(EAX, Address(ESP, + 2 * kWordSize));
+ __ movl(EBX, Address(ESP, + 1 * kWordSize));
+ __ movl(FieldAddress(EAX, GrowableObjectArray::data_offset()), EBX);
+ __ ret();
+ return true;
+}
+
+
// Handles only class InternalByteArray.
static bool ByteArrayBase_getLength(Assembler* assembler) {
ObjectStore* object_store = Isolate::Current()->object_store();
@@ -1251,37 +1354,44 @@
#undef __
-// Returns true if the function matches function_name and class_name, with
-// special recognition of corelib private classes
-static bool TestFunction(const Function& function,
- const char* function_class_name,
- const char* function_name,
- const char* test_class_name,
- const char* test_function_name) {
- if (strcmp(test_function_name, function_name) != 0) return false;
-
- if ((function_class_name[0] == '_') && (test_class_name[0] == '_')) {
+static bool CompareNames(const char* test_name, const char* name) {
+ if (strcmp(test_name, name) == 0) {
+ return true;
+ }
+ if ((name[0] == '_') && (test_name[0] == '_')) {
// Check if the private class is member of corelib and matches the
// test_class_name.
const Library& core_lib = Library::Handle(Library::CoreLibrary());
const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary());
- String& test_str = String::Handle(String::New(test_class_name));
+ String& test_str = String::Handle(String::New(test_name));
String& test_str_with_key = String::Handle();
test_str_with_key =
String::Concat(test_str, String::Handle(core_lib.private_key()));
- if (strcmp(test_str_with_key.ToCString(), function_class_name) == 0) {
+ if (strcmp(test_str_with_key.ToCString(), name) == 0) {
return true;
}
test_str_with_key =
String::Concat(test_str, String::Handle(core_impl_lib.private_key()));
- if (strcmp(test_str_with_key.ToCString(), function_class_name) == 0) {
+ if (strcmp(test_str_with_key.ToCString(), name) == 0) {
return true;
}
}
- return strcmp(test_class_name, function_class_name) == 0;
+ return false;
}
+// Returns true if the function matches function_name and class_name, with
+// special recognition of corelib private classes
+static bool TestFunction(const Function& function,
+ const char* function_class_name,
+ const char* function_name,
+ const char* test_class_name,
+ const char* test_function_name) {
+ return CompareNames(test_class_name, function_class_name) &&
+ CompareNames(test_function_name, function_name);
+}
+
+
bool Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) {
if (!FLAG_intrinsify) return false;
const char* function_name = String::Handle(function.name()).ToCString();

Powered by Google App Engine
This is Rietveld 408576698