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

Side by Side Diff: runtime/vm/opt_code_generator_ia32.cc

Issue 10447064: In generated code for ia32 don't load object's class directly from class_ field. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/opt_code_generator.h" 8 #include "vm/opt_code_generator.h"
9 9
10 #include "vm/assembler_macros.h" 10 #include "vm/assembler_macros.h"
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 VisitLoadTwo(node->left(), node->right(), EAX, EDX); 976 VisitLoadTwo(node->left(), node->right(), EAX, EDX);
977 __ testl(EDX, Immediate(kSmiTagMask)); 977 __ testl(EDX, Immediate(kSmiTagMask));
978 __ j(NOT_ZERO, &slow_case); // Call operator if right is not Smi. 978 __ j(NOT_ZERO, &slow_case); // Call operator if right is not Smi.
979 __ cmpl(EDX, Immediate(0)); 979 __ cmpl(EDX, Immediate(0));
980 __ j(LESS, &slow_case); // Result will not be Smi. 980 __ j(LESS, &slow_case); // Result will not be Smi.
981 981
982 // Test left. 982 // Test left.
983 __ testl(EAX, Immediate(kSmiTagMask)); 983 __ testl(EAX, Immediate(kSmiTagMask));
984 __ j(ZERO, &is_smi); 984 __ j(ZERO, &is_smi);
985 985
986 __ movl(EBX, FieldAddress(EAX, Object::class_offset())); 986 __ CompareClassOfObject(EAX,
987 __ CompareObject(EBX, Class::ZoneHandle(object_store->mint_class())); 987 Class::Handle(object_store->mint_class()),
988 EBX);
988 __ j(NOT_EQUAL, deopt_blob->label()); 989 __ j(NOT_EQUAL, deopt_blob->label());
989 990
990 // Load lower Mint word, convert to Smi. It is OK to loose bits. 991 // Load lower Mint word, convert to Smi. It is OK to loose bits.
991 __ movl(EAX, FieldAddress(EAX, Mint::value_offset())); 992 __ movl(EAX, FieldAddress(EAX, Mint::value_offset()));
992 __ SmiTag(EAX); 993 __ SmiTag(EAX);
993 994
994 __ Bind(&is_smi); 995 __ Bind(&is_smi);
995 __ andl(EAX, EDX); 996 __ andl(EAX, EDX);
996 __ jmp(&done); 997 __ jmp(&done);
997 __ Bind(&slow_case); 998 __ Bind(&slow_case);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 1043
1043 // 'reg' is not modified, 'temp' is trashed. 1044 // 'reg' is not modified, 'temp' is trashed.
1044 // Fall through if double, jump to 'is_smi' if Smi and 1045 // Fall through if double, jump to 'is_smi' if Smi and
1045 // jump to 'not_double_or_smi' if neither double nor Smi. 1046 // jump to 'not_double_or_smi' if neither double nor Smi.
1046 void OptimizingCodeGenerator::CheckIfDoubleOrSmi(Register reg, 1047 void OptimizingCodeGenerator::CheckIfDoubleOrSmi(Register reg,
1047 Register temp, 1048 Register temp,
1048 Label* is_smi, 1049 Label* is_smi,
1049 Label* not_double_or_smi) { 1050 Label* not_double_or_smi) {
1050 __ testl(reg, Immediate(kSmiTagMask)); 1051 __ testl(reg, Immediate(kSmiTagMask));
1051 __ j(ZERO, is_smi); 1052 __ j(ZERO, is_smi);
1052 __ movl(temp, FieldAddress(reg, Object::class_offset())); 1053 __ CompareClassOfObject(reg, double_class_, temp);
1053 __ CompareObject(temp, double_class_);
1054 __ j(NOT_EQUAL, not_double_or_smi); 1054 __ j(NOT_EQUAL, not_double_or_smi);
1055 } 1055 }
1056 1056
1057 1057
1058 // Result of the computation is a newly allocated double object or 1058 // Result of the computation is a newly allocated double object or
1059 // a temporary object if the parent node specifies a CodeGenInfo for this node 1059 // a temporary object if the parent node specifies a CodeGenInfo for this node
1060 // and therefore knows how to handle a temporary. A temporary object cannot 1060 // and therefore knows how to handle a temporary. A temporary object cannot
1061 // be used for long living values (e.g., the ones stored on stack or into other 1061 // be used for long living values (e.g., the ones stored on stack or into other
1062 // objects). 1062 // objects).
1063 // Implement for combinations: Double/Double, Double/Smi, Smi/Double, as 1063 // Implement for combinations: Double/Double, Double/Smi, Smi/Double, as
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 // TODO(srdjan): Do not hardwire register. 1410 // TODO(srdjan): Do not hardwire register.
1411 UNIMPLEMENTED(); 1411 UNIMPLEMENTED();
1412 } 1412 }
1413 DeoptimizationBlob* deopt_blob = 1413 DeoptimizationBlob* deopt_blob =
1414 AddDeoptimizationBlob(node, EBX, kDeoptInstanceGetterSameTarget); 1414 AddDeoptimizationBlob(node, EBX, kDeoptInstanceGetterSameTarget);
1415 if (NodeMayBeSmi(receiver)) { 1415 if (NodeMayBeSmi(receiver)) {
1416 __ testl(EBX, Immediate(kSmiTagMask)); 1416 __ testl(EBX, Immediate(kSmiTagMask));
1417 __ j(ZERO, deopt_blob->label()); 1417 __ j(ZERO, deopt_blob->label());
1418 } 1418 }
1419 1419
1420 __ movl(EAX, FieldAddress(EBX, Object::class_offset())); 1420 __ LoadClassIndexOfObject(EAX, EBX);
1421 const ICData& ic_data = node->ic_data(); 1421 const ICData& ic_data = node->ic_data();
1422 Function& target = Function::Handle(); 1422 Function& target = Function::Handle();
1423 Label load_field; 1423 Label load_field;
1424 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { 1424 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
1425 Class& cls = Class::ZoneHandle(); 1425 Class& cls = Class::Handle();
1426 ic_data.GetOneClassCheckAt(i, &cls, &target); 1426 ic_data.GetOneClassCheckAt(i, &cls, &target);
1427 __ CompareObject(EAX, cls); 1427 __ cmpl(EAX, Immediate(cls.index()));
1428 if (i == (ic_data.NumberOfChecks() - 1)) { 1428 if (i == (ic_data.NumberOfChecks() - 1)) {
1429 __ j(NOT_EQUAL, deopt_blob->label()); 1429 __ j(NOT_EQUAL, deopt_blob->label());
1430 } else { 1430 } else {
1431 __ j(EQUAL, &load_field); 1431 __ j(EQUAL, &load_field);
1432 } 1432 }
1433 } 1433 }
1434 Class& cls = Class::Handle(); 1434 Class& cls = Class::Handle();
1435 ic_data.GetOneClassCheckAt(0, &cls, &target); 1435 ic_data.GetOneClassCheckAt(0, &cls, &target);
1436 1436
1437 __ Bind(&load_field); 1437 __ Bind(&load_field);
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1620 } 1620 }
1621 } 1621 }
1622 // TODO(srdjan): sort classes/target by their invocation count. 1622 // TODO(srdjan): sort classes/target by their invocation count.
1623 DeoptimizationBlob* deopt_blob = AddDeoptimizationBlob( 1623 DeoptimizationBlob* deopt_blob = AddDeoptimizationBlob(
1624 node, recv_reg, value_reg, kDeoptInstanceSetterSameTarget); 1624 node, recv_reg, value_reg, kDeoptInstanceSetterSameTarget);
1625 // Deoptimize if Smi, since they do not have setters. 1625 // Deoptimize if Smi, since they do not have setters.
1626 if (NodeMayBeSmi(receiver)) { 1626 if (NodeMayBeSmi(receiver)) {
1627 __ testl(recv_reg, Immediate(kSmiTagMask)); 1627 __ testl(recv_reg, Immediate(kSmiTagMask));
1628 __ j(ZERO, deopt_blob->label()); 1628 __ j(ZERO, deopt_blob->label());
1629 } 1629 }
1630 __ movl(EBX, FieldAddress(recv_reg, Object::class_offset())); 1630 __ LoadClassIndexOfObject(EBX, recv_reg);
1631 // Initialize setter arguments, but leave the class and target fields NULL. 1631 // Initialize setter arguments, but leave the class and target fields NULL.
1632 InstanceSetterArgs setter_args = 1632 InstanceSetterArgs setter_args =
1633 {NULL, NULL, &field_name, recv_reg, value_reg, 1633 {NULL, NULL, &field_name, recv_reg, value_reg,
1634 node->id(), node->token_index()}; 1634 node->id(), node->token_index()};
1635 1635
1636 if (unique_target) { 1636 if (unique_target) {
1637 Label store_field; 1637 Label store_field;
1638 for (intptr_t i = 0; i < classes.length(); i++) { 1638 for (intptr_t i = 0; i < classes.length(); i++) {
1639 __ CompareObject(EBX, *classes[i]); 1639 __ cmpl(EBX, Immediate(classes[i]->index()));
1640 if (i == (classes.length() - 1)) { 1640 if (i == (classes.length() - 1)) {
1641 __ j(NOT_EQUAL, deopt_blob->label()); 1641 __ j(NOT_EQUAL, deopt_blob->label());
1642 } else { 1642 } else {
1643 __ j(EQUAL, &store_field); 1643 __ j(EQUAL, &store_field);
1644 } 1644 }
1645 } 1645 }
1646 __ Bind(&store_field); 1646 __ Bind(&store_field);
1647 setter_args.cls = classes[0]; 1647 setter_args.cls = classes[0];
1648 setter_args.target = targets[0]; 1648 setter_args.target = targets[0];
1649 GenerateInstanceSetter(setter_args); 1649 GenerateInstanceSetter(setter_args);
1650 return; 1650 return;
1651 } 1651 }
1652 // Targets are different. 1652 // Targets are different.
1653 Label done; 1653 Label done;
1654 for (intptr_t i = 0; i < classes.length(); i++) { 1654 for (intptr_t i = 0; i < classes.length(); i++) {
1655 setter_args.cls = classes[i]; 1655 setter_args.cls = classes[i];
1656 setter_args.target = targets[i]; 1656 setter_args.target = targets[i];
1657 __ CompareObject(EBX, *classes[i]); 1657 __ cmpl(EBX, Immediate(classes[i]->index()));
1658 if (i == (classes.length() - 1)) { 1658 if (i == (classes.length() - 1)) {
1659 __ j(NOT_EQUAL, deopt_blob->label()); 1659 __ j(NOT_EQUAL, deopt_blob->label());
1660 GenerateInstanceSetter(setter_args); 1660 GenerateInstanceSetter(setter_args);
1661 } else { 1661 } else {
1662 Label next_check; 1662 Label next_check;
1663 __ j(NOT_EQUAL, &next_check); 1663 __ j(NOT_EQUAL, &next_check);
1664 GenerateInstanceSetter(setter_args); 1664 GenerateInstanceSetter(setter_args);
1665 __ jmp(&done); 1665 __ jmp(&done);
1666 __ Bind(&next_check); 1666 __ Bind(&next_check);
1667 } 1667 }
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
1983 DeoptimizationBlob* deopt_blob = 1983 DeoptimizationBlob* deopt_blob =
1984 AddDeoptimizationBlob(node, EAX, EDX, kDeoptEqualityNoFeedback); 1984 AddDeoptimizationBlob(node, EAX, EDX, kDeoptEqualityNoFeedback);
1985 __ j(NOT_EQUAL, deopt_blob->label()); 1985 __ j(NOT_EQUAL, deopt_blob->label());
1986 } else { 1986 } else {
1987 DeoptimizationBlob* deopt_blob = 1987 DeoptimizationBlob* deopt_blob =
1988 AddDeoptimizationBlob(node, EAX, EDX, kDeoptEqualityClassCheck); 1988 AddDeoptimizationBlob(node, EAX, EDX, kDeoptEqualityClassCheck);
1989 __ j(EQUAL, &compare); 1989 __ j(EQUAL, &compare);
1990 // Smi causes deoptimization. 1990 // Smi causes deoptimization.
1991 __ testl(EAX, Immediate(kSmiTagMask)); 1991 __ testl(EAX, Immediate(kSmiTagMask));
1992 __ j(ZERO, deopt_blob->label()); 1992 __ j(ZERO, deopt_blob->label());
1993 __ movl(EBX, FieldAddress(EAX, Object::class_offset())); 1993 __ LoadClassIndexOfObject(EBX, EAX);
1994 for (intptr_t i = 0; i < num_classes; i++) { 1994 for (intptr_t i = 0; i < num_classes; i++) {
1995 const Class& cls = *(*classes)[i]; 1995 const Class& cls = *(*classes)[i];
1996 __ CompareObject(EBX, cls); 1996 __ cmpl(EBX, Immediate(cls.index()));
1997 if (i == (num_classes - 1)) { 1997 if (i == (num_classes - 1)) {
1998 __ j(NOT_EQUAL, deopt_blob->label()); 1998 __ j(NOT_EQUAL, deopt_blob->label());
1999 } else { 1999 } else {
2000 __ j(EQUAL, &compare); 2000 __ j(EQUAL, &compare);
2001 } 2001 }
2002 } 2002 }
2003 } 2003 }
2004 __ Bind(&compare); 2004 __ Bind(&compare);
2005 __ cmpl(EAX, EDX); 2005 __ cmpl(EAX, EDX);
2006 if (NodeInfoHasLabels(node)) { 2006 if (NodeInfoHasLabels(node)) {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
2164 CodeGenInfo index_info(node->index_expr()); 2164 CodeGenInfo index_info(node->index_expr());
2165 VisitLoadTwo(node->array(), node->index_expr(), EBX, EDX); 2165 VisitLoadTwo(node->array(), node->index_expr(), EBX, EDX);
2166 DeoptimizationBlob* deopt_blob = 2166 DeoptimizationBlob* deopt_blob =
2167 AddDeoptimizationBlob(node, EBX, EDX, kDeoptLoadIndexedFixedArray); 2167 AddDeoptimizationBlob(node, EBX, EDX, kDeoptLoadIndexedFixedArray);
2168 const Class& test_class = NodeHasClassAt(node, object_array_class, 0) ? 2168 const Class& test_class = NodeHasClassAt(node, object_array_class, 0) ?
2169 object_array_class : immutable_object_array_class; 2169 object_array_class : immutable_object_array_class;
2170 // Type checks of array. 2170 // Type checks of array.
2171 if (!array_info.IsClass(test_class)) { 2171 if (!array_info.IsClass(test_class)) {
2172 __ testl(EBX, Immediate(kSmiTagMask)); // Deoptimize if Smi. 2172 __ testl(EBX, Immediate(kSmiTagMask)); // Deoptimize if Smi.
2173 __ j(ZERO, deopt_blob->label()); 2173 __ j(ZERO, deopt_blob->label());
2174 __ movl(EAX, FieldAddress(EBX, Object::class_offset())); 2174 __ CompareClassOfObject(EBX, test_class, EAX);
2175 __ CompareObject(EAX, test_class);
2176 __ j(NOT_EQUAL, deopt_blob->label()); 2175 __ j(NOT_EQUAL, deopt_blob->label());
2177 PropagateBackLocalClass(node->array(), test_class); 2176 PropagateBackLocalClass(node->array(), test_class);
2178 } 2177 }
2179 2178
2180 // Type check of index. 2179 // Type check of index.
2181 if (!index_info.IsClass(smi_class_)) { 2180 if (!index_info.IsClass(smi_class_)) {
2182 __ testl(EDX, Immediate(kSmiTagMask)); 2181 __ testl(EDX, Immediate(kSmiTagMask));
2183 __ j(NOT_ZERO, deopt_blob->label()); 2182 __ j(NOT_ZERO, deopt_blob->label());
2184 PropagateBackLocalClass(node->index_expr(), smi_class_); 2183 PropagateBackLocalClass(node->index_expr(), smi_class_);
2185 } 2184 }
(...skipping 16 matching lines...) Expand all
2202 AddDeoptimizationBlob(node, EDX, EAX, kDeoptLoadIndexedGrowableArray); 2201 AddDeoptimizationBlob(node, EDX, EAX, kDeoptLoadIndexedGrowableArray);
2203 // EAX: index, EDX: array. 2202 // EAX: index, EDX: array.
2204 if (!index_info.IsClass(smi_class_)) { 2203 if (!index_info.IsClass(smi_class_)) {
2205 __ testl(EAX, Immediate(kSmiTagMask)); 2204 __ testl(EAX, Immediate(kSmiTagMask));
2206 __ j(NOT_ZERO, deopt_blob->label()); // Not Smi index. 2205 __ j(NOT_ZERO, deopt_blob->label()); // Not Smi index.
2207 PropagateBackLocalClass(node->index_expr(), smi_class_); 2206 PropagateBackLocalClass(node->index_expr(), smi_class_);
2208 } 2207 }
2209 if (!array_info.IsClass(growable_object_array_class_)) { 2208 if (!array_info.IsClass(growable_object_array_class_)) {
2210 __ testl(EDX, Immediate(kSmiTagMask)); 2209 __ testl(EDX, Immediate(kSmiTagMask));
2211 __ j(ZERO, deopt_blob->label()); // Array is Smi. 2210 __ j(ZERO, deopt_blob->label()); // Array is Smi.
2212 __ movl(EBX, FieldAddress(EDX, Object::class_offset())); 2211 __ CompareClassOfObject(EDX, growable_object_array_class_, EBX);
2213 __ CompareObject(EBX, growable_object_array_class_);
2214 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray. 2212 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray.
2215 PropagateBackLocalClass(node->array(), growable_object_array_class_); 2213 PropagateBackLocalClass(node->array(), growable_object_array_class_);
2216 } 2214 }
2217 // Range check: deoptimize if out of bounds. 2215 // Range check: deoptimize if out of bounds.
2218 __ cmpl(EAX, FieldAddress(EDX, GrowableObjectArray::length_offset())); 2216 __ cmpl(EAX, FieldAddress(EDX, GrowableObjectArray::length_offset()));
2219 __ j(ABOVE_EQUAL, deopt_blob->label()); 2217 __ j(ABOVE_EQUAL, deopt_blob->label());
2220 __ movl(EDX, FieldAddress(EDX, GrowableObjectArray::data_offset())); 2218 __ movl(EDX, FieldAddress(EDX, GrowableObjectArray::data_offset()));
2221 // Note that EAX is Smi, i.e, times 2. 2219 // Note that EAX is Smi, i.e, times 2.
2222 ASSERT(kSmiTagShift == 1); 2220 ASSERT(kSmiTagShift == 1);
2223 __ movl(EAX, FieldAddress(EDX, EAX, TIMES_2, sizeof(RawArray))); 2221 __ movl(EAX, FieldAddress(EDX, EAX, TIMES_2, sizeof(RawArray)));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2270 VisitLoadOne(node->value(), ECX); 2268 VisitLoadOne(node->value(), ECX);
2271 DeoptimizationBlob* deopt_blob = 2269 DeoptimizationBlob* deopt_blob =
2272 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed); 2270 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed);
2273 __ popl(EBX); // index. 2271 __ popl(EBX); // index.
2274 __ popl(EAX); // array. 2272 __ popl(EAX); // array.
2275 // ECX: value, EBX:index, EAX: array. 2273 // ECX: value, EBX:index, EAX: array.
2276 // Check class of array. 2274 // Check class of array.
2277 if (class_of_this_array.raw() != object_array_class.raw()) { 2275 if (class_of_this_array.raw() != object_array_class.raw()) {
2278 __ testl(EAX, Immediate(kSmiTagMask)); 2276 __ testl(EAX, Immediate(kSmiTagMask));
2279 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt. 2277 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt.
2280 __ movl(EDX, FieldAddress(EAX, Object::class_offset())); 2278 __ CompareClassOfObject(EAX, object_array_class, EDX);
2281 __ CompareObject(EDX, object_array_class);
2282 __ j(NOT_EQUAL, deopt_blob->label()); // Not ObjectArray -> deopt. 2279 __ j(NOT_EQUAL, deopt_blob->label()); // Not ObjectArray -> deopt.
2283 PropagateBackLocalClass(node->array(), object_array_class); 2280 PropagateBackLocalClass(node->array(), object_array_class);
2284 } 2281 }
2285 // Check class of index. 2282 // Check class of index.
2286 if (!index_is_smi) { 2283 if (!index_is_smi) {
2287 __ testl(EBX, Immediate(kSmiTagMask)); 2284 __ testl(EBX, Immediate(kSmiTagMask));
2288 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt. 2285 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
2289 PropagateBackLocalClass(node->index_expr(), smi_class_); 2286 PropagateBackLocalClass(node->index_expr(), smi_class_);
2290 } 2287 }
2291 // Range check. 2288 // Range check.
(...skipping 19 matching lines...) Expand all
2311 VisitLoadOne(node->value(), ECX); 2308 VisitLoadOne(node->value(), ECX);
2312 DeoptimizationBlob* deopt_blob = 2309 DeoptimizationBlob* deopt_blob =
2313 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed); 2310 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed);
2314 __ popl(EBX); // index. 2311 __ popl(EBX); // index.
2315 __ popl(EAX); // array. 2312 __ popl(EAX); // array.
2316 // ECX: value, EBX:index, EAX: array, EDX: scratch. 2313 // ECX: value, EBX:index, EAX: array, EDX: scratch.
2317 // Check class of array. 2314 // Check class of array.
2318 if (class_of_this_array.raw() != growable_object_array_class_.raw()) { 2315 if (class_of_this_array.raw() != growable_object_array_class_.raw()) {
2319 __ testl(EAX, Immediate(kSmiTagMask)); 2316 __ testl(EAX, Immediate(kSmiTagMask));
2320 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt. 2317 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt.
2321 __ movl(EDX, FieldAddress(EAX, Object::class_offset())); 2318 __ CompareClassOfObject(EAX, growable_object_array_class_, EDX);
2322 __ CompareObject(EDX, growable_object_array_class_);
2323 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray. 2319 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray.
2324 PropagateBackLocalClass(node->array(), growable_object_array_class_); 2320 PropagateBackLocalClass(node->array(), growable_object_array_class_);
2325 } 2321 }
2326 // Check class of index. 2322 // Check class of index.
2327 if (!index_is_smi) { 2323 if (!index_is_smi) {
2328 __ testl(EBX, Immediate(kSmiTagMask)); 2324 __ testl(EBX, Immediate(kSmiTagMask));
2329 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt. 2325 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
2330 PropagateBackLocalClass(node->index_expr(), smi_class_); 2326 PropagateBackLocalClass(node->index_expr(), smi_class_);
2331 } 2327 }
2332 // Range check: deoptimize if out of bounds. 2328 // Range check: deoptimize if out of bounds.
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
2640 __ jmp(&done); 2636 __ jmp(&done);
2641 __ Bind(&not_smi); // Continue with other test below. 2637 __ Bind(&not_smi); // Continue with other test below.
2642 } else if (NodeMayBeSmi(receiver)) { 2638 } else if (NodeMayBeSmi(receiver)) {
2643 DeoptimizationBlob* deopt_blob = 2639 DeoptimizationBlob* deopt_blob =
2644 AddDeoptimizationBlob(node, kDeoptCheckedInstanceCallSmiFail); 2640 AddDeoptimizationBlob(node, kDeoptCheckedInstanceCallSmiFail);
2645 __ testl(EAX, Immediate(kSmiTagMask)); 2641 __ testl(EAX, Immediate(kSmiTagMask));
2646 __ j(ZERO, deopt_blob->label()); 2642 __ j(ZERO, deopt_blob->label());
2647 } else { 2643 } else {
2648 // Receiver cannot be Smi, no need to test it. 2644 // Receiver cannot be Smi, no need to test it.
2649 } 2645 }
2650 __ movl(EAX, FieldAddress(EAX, Object::class_offset())); // Receiver's class. 2646 __ LoadClassIndexOfObject(EAX, EAX); // Receiver's class.
2651 for (intptr_t i = start_ix; i < classes.length(); i++) { 2647 for (intptr_t i = start_ix; i < classes.length(); i++) {
2652 const Class& cls = *classes[i]; 2648 const Class& cls = *classes[i];
2653 const Function& target = *targets[i]; 2649 const Function& target = *targets[i];
2654 __ CompareObject(EAX, cls); 2650 __ cmpl(EAX, Immediate(cls.index()));
2655 if (i == (classes.length() - 1)) { 2651 if (i == (classes.length() - 1)) {
2656 // Last check. 2652 // Last check.
2657 DeoptimizationBlob* deopt_blob = 2653 DeoptimizationBlob* deopt_blob =
2658 AddDeoptimizationBlob(node, kDeoptCheckedInstanceCallCheckFail); 2654 AddDeoptimizationBlob(node, kDeoptCheckedInstanceCallCheckFail);
2659 __ j(NOT_EQUAL, deopt_blob->label()); 2655 __ j(NOT_EQUAL, deopt_blob->label());
2660 GenerateDirectCall(node->id(), 2656 GenerateDirectCall(node->id(),
2661 token_index, 2657 token_index,
2662 target, 2658 target,
2663 num_args, 2659 num_args,
2664 optional_arguments_names); 2660 optional_arguments_names);
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
2901 } 2897 }
2902 } 2898 }
2903 // TODO(srdjan): Implement unary kSUB (negate) Mint. 2899 // TODO(srdjan): Implement unary kSUB (negate) Mint.
2904 CodeGenerator::VisitUnaryOpNode(node); 2900 CodeGenerator::VisitUnaryOpNode(node);
2905 } 2901 }
2906 2902
2907 2903
2908 } // namespace dart 2904 } // namespace dart
2909 2905
2910 #endif // defined TARGET_ARCH_IA32 2906 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698