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

Unified Diff: runtime/vm/opt_code_generator_ia32.cc

Issue 9022019: Do back propagation of types(classes) for checks in load and store indexed. (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 | « no previous file | no next file » | 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 2792)
+++ runtime/vm/opt_code_generator_ia32.cc (working copy)
@@ -700,13 +700,19 @@
// TODO(srdjan): Implement for Mint?
DeoptimizationBlob* deopt_blob =
AddDeoptimizationBlob(node, EAX, ECX, kDeoptSAR);
+ CodeGenInfo left_info(node->left());
+ CodeGenInfo right_info(node->right());
// EAX: value to shift, ECX: amount to shift.
VisitLoadTwo(node->left(), node->right(), EAX, ECX);
- // Check if both Smi.
- __ movl(EBX, EAX);
- __ orl(EBX, ECX);
- __ testl(EBX, Immediate(kSmiTagMask));
- __ j(NOT_ZERO, deopt_blob->label());
+ if (!left_info.IsClass(smi_class_) || !right_info.IsClass(smi_class_)) {
+ // Check if both Smi.
+ __ movl(EBX, EAX);
+ __ orl(EBX, ECX);
+ __ testl(EBX, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, deopt_blob->label());
+ PropagateBackLocalClass(node->left(), smi_class_);
+ PropagateBackLocalClass(node->right(), smi_class_);
+ }
Immediate count_limit = Immediate(0x1F);
__ SmiUntag(ECX);
__ cmpl(ECX, count_limit);
@@ -729,9 +735,12 @@
smi ^= node->right()->AsLiteralNode()->literal().raw();
if (smi.Value() < Smi::kBits) {
Label slow_case;
+ CodeGenInfo left_info(node->left());
VisitLoadOne(node->left(), EAX);
- __ testl(EAX, Immediate(kSmiTagMask));
- __ j(NOT_ZERO, &slow_case, Assembler::kNearJump); // left not smi
+ if (!left_info.IsClass(smi_class_)) {
+ __ testl(EAX, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, &slow_case, Assembler::kNearJump); // left not smi
+ }
// Overflow test.
__ movl(EBX, EAX);
Immediate imm(smi.Value());
@@ -758,14 +767,18 @@
}
Label slow_case, done;
+ CodeGenInfo left_info(node->left());
+ CodeGenInfo right_info(node->right());
VisitLoadTwo(node->left(), node->right(), EAX, EDX);
// TODO(srdjan): Better code for count being a Smi literal.
// EAX: value, EDX: shift amount. Preserve them for slow case.
// Fast case only if both ar Smi.
- __ movl(EBX, EAX);
- __ orl(EBX, EDX);
- __ testl(EBX, Immediate(kSmiTagMask));
- __ j(NOT_ZERO, &slow_case, Assembler::kNearJump);
+ if (!left_info.IsClass(smi_class_) || !right_info.IsClass(smi_class_)) {
+ __ movl(EBX, EAX);
+ __ orl(EBX, EDX);
+ __ testl(EBX, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, &slow_case, Assembler::kNearJump);
+ }
// Check if count too large for handling it inlined.
__ cmpl(EDX, Immediate(reinterpret_cast<int32_t>(Smi::New(Smi::kBits))));
__ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump);
@@ -813,8 +826,11 @@
return;
}
ASSERT(ic_data.NumberOfChecks() == 1);
- __ testl(EAX, Immediate(kSmiTagMask));
- __ j(NOT_ZERO, deopt_blob->label());
+ if (!info.IsClass(smi_class_)) {
+ __ testl(EAX, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, deopt_blob->label());
+ PropagateBackLocalClass(node->operand(), smi_class_);
+ }
if (node->kind() == Token::kSUB) {
__ negl(EAX);
__ j(OVERFLOW, deopt_blob->label());
@@ -2374,6 +2390,8 @@
if (AtIdNodeHasClassAt(node, node->id(), object_array_class, 0) ||
AtIdNodeHasClassAt(node, node->id(),
immutable_object_array_class, 0)) {
+ CodeGenInfo array_info(node->array());
+ CodeGenInfo index_info(node->index_expr());
VisitLoadTwo(node->array(), node->index_expr(), EBX, EDX);
DeoptimizationBlob* deopt_blob =
AddDeoptimizationBlob(node, EBX, EDX, kDeoptLoadIndexedFixedArray);
@@ -2381,15 +2399,21 @@
AtIdNodeHasClassAt(node, node->id(), object_array_class, 0) ?
object_array_class : immutable_object_array_class;
// Type checks of array.
- __ testl(EBX, Immediate(kSmiTagMask)); // Deoptimize if Smi.
- __ j(ZERO, deopt_blob->label());
- __ movl(EAX, FieldAddress(EBX, Object::class_offset()));
- __ CompareObject(EAX, test_class);
- __ j(NOT_EQUAL, deopt_blob->label());
+ if (!array_info.IsClass(test_class)) {
+ __ testl(EBX, Immediate(kSmiTagMask)); // Deoptimize if Smi.
+ __ j(ZERO, deopt_blob->label());
+ __ movl(EAX, FieldAddress(EBX, Object::class_offset()));
+ __ CompareObject(EAX, test_class);
+ __ j(NOT_EQUAL, deopt_blob->label());
+ PropagateBackLocalClass(node->array(), test_class);
+ }
// Type check of index.
- __ testl(EDX, Immediate(kSmiTagMask));
- __ j(NOT_ZERO, deopt_blob->label());
+ if (!index_info.IsClass(smi_class_)) {
+ __ testl(EDX, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, deopt_blob->label());
+ PropagateBackLocalClass(node->index_expr(), smi_class_);
+ }
// Range check.
__ cmpl(EDX, FieldAddress(EBX, Array::length_offset()));
__ j(ABOVE_EQUAL, deopt_blob->label());
@@ -2416,18 +2440,25 @@
growable_array_length_field_name);
intptr_t array_offset = GetFieldOffset(growable_array_class,
growable_array_array_field_name);
+ CodeGenInfo array_info(node->array());
+ CodeGenInfo index_info(node->index_expr());
VisitLoadTwo(node->array(), node->index_expr(), EDX, EAX);
DeoptimizationBlob* deopt_blob =
AddDeoptimizationBlob(node, EDX, EAX, kDeoptLoadIndexedGrowableArray);
- // TODO(srdjan): Use CodeGenInfo to eliminate Smi test if possible.
// EAX: index, EDX: array.
- __ testl(EAX, Immediate(kSmiTagMask));
- __ j(NOT_ZERO, deopt_blob->label()); // Not Smi index.
- __ testl(EDX, Immediate(kSmiTagMask));
- __ j(ZERO, deopt_blob->label()); // Array is Smi.
- __ movl(EBX, FieldAddress(EDX, Object::class_offset()));
- __ CompareObject(EBX, growable_array_class);
- __ j(NOT_EQUAL, deopt_blob->label()); // Array is not GrowableObjectArray.
+ if (!index_info.IsClass(smi_class_)) {
+ __ testl(EAX, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, deopt_blob->label()); // Not Smi index.
+ PropagateBackLocalClass(node->index_expr(), smi_class_);
+ }
+ if (!array_info.IsClass(growable_array_class)) {
+ __ testl(EDX, Immediate(kSmiTagMask));
+ __ j(ZERO, deopt_blob->label()); // Array is Smi.
+ __ movl(EBX, FieldAddress(EDX, Object::class_offset()));
+ __ CompareObject(EBX, growable_array_class);
+ __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray.
+ PropagateBackLocalClass(node->array(), growable_array_class);
+ }
// Range check: deoptimize if out of bounds.
__ cmpl(EAX, FieldAddress(EDX, length_offset));
__ j(ABOVE_EQUAL, deopt_blob->label());
@@ -2464,6 +2495,9 @@
return;
}
+ CodeGenInfo array_info(node->array());
+ CodeGenInfo index_info(node->index_expr());
+
if (AtIdNodeHasClassAt(node, node->id(), object_array_class, 0)) {
VisitLoadTwo(node->index_expr(), node->value(), EBX, ECX);
DeoptimizationBlob* deopt_blob =
@@ -2471,14 +2505,20 @@
__ popl(EAX); // array.
// ECX: value, EBX:index, EAX: 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.
+ if (!array_info.IsClass(object_array_class)) {
+ __ 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.
+ PropagateBackLocalClass(node->array(), object_array_class);
+ }
// Check class of index.
- __ testl(EBX, Immediate(kSmiTagMask));
- __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
+ if (!index_info.IsClass(smi_class_)) {
+ __ testl(EBX, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
+ PropagateBackLocalClass(node->index_expr(), smi_class_);
+ }
// Range check.
__ cmpl(EBX, FieldAddress(EAX, Array::length_offset()));
__ j(ABOVE_EQUAL, deopt_blob->label()); // Range error -> deopt.
@@ -2511,14 +2551,20 @@
__ 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.
+ if (!array_info.IsClass(growable_array_class)) {
+ __ 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.
+ PropagateBackLocalClass(node->array(), growable_array_class);
+ }
// Check class of index.
- __ testl(EBX, Immediate(kSmiTagMask));
- __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
+ if (!index_info.IsClass(smi_class_)) {
+ __ testl(EBX, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
+ PropagateBackLocalClass(node->index_expr(), smi_class_);
+ }
// Range check: deoptimize if out of bounds.
__ cmpl(EBX, FieldAddress(EAX, length_offset));
__ j(ABOVE_EQUAL, deopt_blob->label());
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698