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

Unified Diff: runtime/vm/opt_code_generator_ia32.cc

Issue 9020030: Optimize indexed store for growable array (intrinsification and inlined optimized). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years 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
« no previous file with comments | « runtime/vm/intrinsifier_ia32.cc ('k') | tests/language/src/OptimizationTest.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/opt_code_generator_ia32.cc
===================================================================
--- runtime/vm/opt_code_generator_ia32.cc (revision 2725)
+++ runtime/vm/opt_code_generator_ia32.cc (working copy)
@@ -2360,6 +2360,7 @@
const Class& growable_array_class = Class::ZoneHandle(
Library::Handle(Library::CoreImplLibrary()).
LookupClass(growable_object_array_class_name));
+ ASSERT(!growable_array_class.IsNull());
if (AtIdNodeHasOnlyClass(node, node->id(), growable_array_class)) {
const String& growable_array_length_field_name =
String::Handle(String::NewSymbol(kGrowableArrayLengthFieldName));
@@ -2418,19 +2419,20 @@
__ jmp(deopt_blob->label());
return;
}
+
if (AtIdNodeHasOnlyClass(node, node->id(), object_array_class)) {
VisitLoadTwo(node->index_expr(), node->value(), EBX, ECX);
DeoptimizationBlob* deopt_blob =
AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed);
__ popl(EAX); // array.
// ECX: value, EBX:index, EAX: array.
- // Check type of array.
+ // Check class of array.
__ testl(EAX, Immediate(kSmiTagMask));
__ j(ZERO, deopt_blob->label()); // Array is smi -> deopt.
__ movl(EDX, FieldAddress(EAX, Object::class_offset()));
__ CompareObject(EDX, object_array_class);
__ j(NOT_EQUAL, deopt_blob->label()); // Not ObjectArray -> deopt.
- // Check type of index.
+ // Check class of index.
__ testl(EBX, Immediate(kSmiTagMask));
__ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
// Range check.
@@ -2445,6 +2447,50 @@
}
return;
}
+
+ const String& growable_object_array_class_name = String::Handle(
+ String::NewSymbol(kGrowableArrayClassName));
+ const Class& growable_array_class = Class::ZoneHandle(
+ Library::Handle(Library::CoreImplLibrary()).
+ LookupClass(growable_object_array_class_name));
+ ASSERT(!growable_array_class.IsNull());
+ if (AtIdNodeHasOnlyClass(node, node->id(), growable_array_class)) {
+ const String& growable_array_length_field_name =
+ String::Handle(String::NewSymbol(kGrowableArrayLengthFieldName));
+ const String& growable_array_array_field_name =
+ String::Handle(String::NewSymbol(kGrowableArrayArrayFieldName));
+ intptr_t length_offset = GetFieldOffset(growable_array_class,
+ growable_array_length_field_name);
+ intptr_t array_offset = GetFieldOffset(growable_array_class,
+ growable_array_array_field_name);
+ VisitLoadTwo(node->index_expr(), node->value(), EBX, ECX);
+ DeoptimizationBlob* deopt_blob =
+ AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed);
+ __ popl(EAX); // Array.
+ // ECX: value, EBX:index, EAX: array, EDX: scratch.
+ // Check class of array.
+ __ testl(EAX, Immediate(kSmiTagMask));
+ __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt.
+ __ movl(EDX, FieldAddress(EAX, Object::class_offset()));
+ __ CompareObject(EDX, growable_array_class);
+ __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray -> deopt.
+ // Check class of index.
+ __ testl(EBX, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
+ // Range check: deoptimize if out of bounds.
+ __ cmpl(EBX, FieldAddress(EAX, length_offset));
+ __ j(ABOVE_EQUAL, deopt_blob->label());
+ __ movl(EDX, FieldAddress(EAX, array_offset)); // backingArray.
+ // Note that EAX is Smi, i.e, times 2.
+ ASSERT(kSmiTagShift == 1);
+ __ StoreIntoObject(EDX,
+ FieldAddress(EDX, EBX, TIMES_2, sizeof(RawArray)),
+ ECX);
+ if (CodeGenerator::IsResultNeeded(node)) {
+ __ pushl(ECX);
+ }
+ return;
+ }
node->index_expr()->Visit(this);
node->value()->Visit(this);
GenerateStoreIndexed(node->id(), node->token_index(), IsResultNeeded(node));
« no previous file with comments | « runtime/vm/intrinsifier_ia32.cc ('k') | tests/language/src/OptimizationTest.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698