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

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

Issue 10458031: In generated code for x64 don't load object's class directly from class_ field. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Eliminate CoreClass helpers on ia32/x64 and use class ids for array classes. 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
« no previous file with comments | « runtime/vm/intrinsifier_ia32.cc ('k') | runtime/vm/stub_code_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 948 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 } 959 }
960 960
961 961
962 // Supports some mixed Smi/Mint operations. 962 // Supports some mixed Smi/Mint operations.
963 // For BIT_AND operation with right operand being Smi, we can throw away 963 // For BIT_AND operation with right operand being Smi, we can throw away
964 // any Mint bits above the Smi range as long as the right operand is positive. 964 // any Mint bits above the Smi range as long as the right operand is positive.
965 // 'allow_smi' is true if Smi and Mint classes have been encountered. 965 // 'allow_smi' is true if Smi and Mint classes have been encountered.
966 void OptimizingCodeGenerator::GenerateMintBinaryOp(BinaryOpNode* node, 966 void OptimizingCodeGenerator::GenerateMintBinaryOp(BinaryOpNode* node,
967 bool allow_smi) { 967 bool allow_smi) {
968 const char* kOptMessage = "Inline Mint binop."; 968 const char* kOptMessage = "Inline Mint binop.";
969 ObjectStore* object_store = Isolate::Current()->object_store();
970 const Token::Kind kind = node->kind(); 969 const Token::Kind kind = node->kind();
971 if (kind == Token::kBIT_AND) { 970 if (kind == Token::kBIT_AND) {
972 TraceOpt(node, kOptMessage); 971 TraceOpt(node, kOptMessage);
973 Label is_smi, slow_case, done; 972 Label is_smi, slow_case, done;
974 DeoptimizationBlob* deopt_blob = 973 DeoptimizationBlob* deopt_blob =
975 AddDeoptimizationBlob(node, EAX, EDX, kDeoptMintBinaryOp); 974 AddDeoptimizationBlob(node, EAX, EDX, kDeoptMintBinaryOp);
976 VisitLoadTwo(node->left(), node->right(), EAX, EDX); 975 VisitLoadTwo(node->left(), node->right(), EAX, EDX);
977 __ testl(EDX, Immediate(kSmiTagMask)); 976 __ testl(EDX, Immediate(kSmiTagMask));
978 __ j(NOT_ZERO, &slow_case); // Call operator if right is not Smi. 977 __ j(NOT_ZERO, &slow_case); // Call operator if right is not Smi.
979 __ cmpl(EDX, Immediate(0)); 978 __ cmpl(EDX, Immediate(0));
980 __ j(LESS, &slow_case); // Result will not be Smi. 979 __ j(LESS, &slow_case); // Result will not be Smi.
981 980
982 // Test left. 981 // Test left.
983 __ testl(EAX, Immediate(kSmiTagMask)); 982 __ testl(EAX, Immediate(kSmiTagMask));
984 __ j(ZERO, &is_smi); 983 __ j(ZERO, &is_smi);
985 984
986 __ CompareClassOfObject(EAX, 985 __ CompareClassId(EAX, kMint, EBX);
987 Class::Handle(object_store->mint_class()),
988 EBX);
989 __ j(NOT_EQUAL, deopt_blob->label()); 986 __ j(NOT_EQUAL, deopt_blob->label());
990 987
991 // Load lower Mint word, convert to Smi. It is OK to loose bits. 988 // Load lower Mint word, convert to Smi. It is OK to loose bits.
992 __ movl(EAX, FieldAddress(EAX, Mint::value_offset())); 989 __ movl(EAX, FieldAddress(EAX, Mint::value_offset()));
993 __ SmiTag(EAX); 990 __ SmiTag(EAX);
994 991
995 __ Bind(&is_smi); 992 __ Bind(&is_smi);
996 __ andl(EAX, EDX); 993 __ andl(EAX, EDX);
997 __ jmp(&done); 994 __ jmp(&done);
998 __ Bind(&slow_case); 995 __ Bind(&slow_case);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 1040
1044 // 'reg' is not modified, 'temp' is trashed. 1041 // 'reg' is not modified, 'temp' is trashed.
1045 // Fall through if double, jump to 'is_smi' if Smi and 1042 // Fall through if double, jump to 'is_smi' if Smi and
1046 // jump to 'not_double_or_smi' if neither double nor Smi. 1043 // jump to 'not_double_or_smi' if neither double nor Smi.
1047 void OptimizingCodeGenerator::CheckIfDoubleOrSmi(Register reg, 1044 void OptimizingCodeGenerator::CheckIfDoubleOrSmi(Register reg,
1048 Register temp, 1045 Register temp,
1049 Label* is_smi, 1046 Label* is_smi,
1050 Label* not_double_or_smi) { 1047 Label* not_double_or_smi) {
1051 __ testl(reg, Immediate(kSmiTagMask)); 1048 __ testl(reg, Immediate(kSmiTagMask));
1052 __ j(ZERO, is_smi); 1049 __ j(ZERO, is_smi);
1053 __ CompareClassOfObject(reg, double_class_, temp); 1050 __ CompareClassId(reg, kDouble, temp);
1054 __ j(NOT_EQUAL, not_double_or_smi); 1051 __ j(NOT_EQUAL, not_double_or_smi);
1055 } 1052 }
1056 1053
1057 1054
1058 // Result of the computation is a newly allocated double object or 1055 // 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 1056 // 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 1057 // 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 1058 // be used for long living values (e.g., the ones stored on stack or into other
1062 // objects). 1059 // objects).
1063 // Implement for combinations: Double/Double, Double/Smi, Smi/Double, as 1060 // 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. 1407 // TODO(srdjan): Do not hardwire register.
1411 UNIMPLEMENTED(); 1408 UNIMPLEMENTED();
1412 } 1409 }
1413 DeoptimizationBlob* deopt_blob = 1410 DeoptimizationBlob* deopt_blob =
1414 AddDeoptimizationBlob(node, EBX, kDeoptInstanceGetterSameTarget); 1411 AddDeoptimizationBlob(node, EBX, kDeoptInstanceGetterSameTarget);
1415 if (NodeMayBeSmi(receiver)) { 1412 if (NodeMayBeSmi(receiver)) {
1416 __ testl(EBX, Immediate(kSmiTagMask)); 1413 __ testl(EBX, Immediate(kSmiTagMask));
1417 __ j(ZERO, deopt_blob->label()); 1414 __ j(ZERO, deopt_blob->label());
1418 } 1415 }
1419 1416
1420 __ LoadClassIndexOfObject(EAX, EBX); 1417 __ LoadClassId(EAX, EBX);
1421 const ICData& ic_data = node->ic_data(); 1418 const ICData& ic_data = node->ic_data();
1422 Function& target = Function::Handle(); 1419 Function& target = Function::Handle();
1423 Label load_field; 1420 Label load_field;
1424 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { 1421 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
1425 Class& cls = Class::Handle(); 1422 Class& cls = Class::Handle();
1426 ic_data.GetOneClassCheckAt(i, &cls, &target); 1423 ic_data.GetOneClassCheckAt(i, &cls, &target);
1427 __ cmpl(EAX, Immediate(cls.index())); 1424 __ cmpl(EAX, Immediate(cls.index()));
1428 if (i == (ic_data.NumberOfChecks() - 1)) { 1425 if (i == (ic_data.NumberOfChecks() - 1)) {
1429 __ j(NOT_EQUAL, deopt_blob->label()); 1426 __ j(NOT_EQUAL, deopt_blob->label());
1430 } else { 1427 } else {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1620 } 1617 }
1621 } 1618 }
1622 // TODO(srdjan): sort classes/target by their invocation count. 1619 // TODO(srdjan): sort classes/target by their invocation count.
1623 DeoptimizationBlob* deopt_blob = AddDeoptimizationBlob( 1620 DeoptimizationBlob* deopt_blob = AddDeoptimizationBlob(
1624 node, recv_reg, value_reg, kDeoptInstanceSetterSameTarget); 1621 node, recv_reg, value_reg, kDeoptInstanceSetterSameTarget);
1625 // Deoptimize if Smi, since they do not have setters. 1622 // Deoptimize if Smi, since they do not have setters.
1626 if (NodeMayBeSmi(receiver)) { 1623 if (NodeMayBeSmi(receiver)) {
1627 __ testl(recv_reg, Immediate(kSmiTagMask)); 1624 __ testl(recv_reg, Immediate(kSmiTagMask));
1628 __ j(ZERO, deopt_blob->label()); 1625 __ j(ZERO, deopt_blob->label());
1629 } 1626 }
1630 __ LoadClassIndexOfObject(EBX, recv_reg); 1627 __ LoadClassId(EBX, recv_reg);
1631 // Initialize setter arguments, but leave the class and target fields NULL. 1628 // Initialize setter arguments, but leave the class and target fields NULL.
1632 InstanceSetterArgs setter_args = 1629 InstanceSetterArgs setter_args =
1633 {NULL, NULL, &field_name, recv_reg, value_reg, 1630 {NULL, NULL, &field_name, recv_reg, value_reg,
1634 node->id(), node->token_index()}; 1631 node->id(), node->token_index()};
1635 1632
1636 if (unique_target) { 1633 if (unique_target) {
1637 Label store_field; 1634 Label store_field;
1638 for (intptr_t i = 0; i < classes.length(); i++) { 1635 for (intptr_t i = 0; i < classes.length(); i++) {
1639 __ cmpl(EBX, Immediate(classes[i]->index())); 1636 __ cmpl(EBX, Immediate(classes[i]->index()));
1640 if (i == (classes.length() - 1)) { 1637 if (i == (classes.length() - 1)) {
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
1983 DeoptimizationBlob* deopt_blob = 1980 DeoptimizationBlob* deopt_blob =
1984 AddDeoptimizationBlob(node, EAX, EDX, kDeoptEqualityNoFeedback); 1981 AddDeoptimizationBlob(node, EAX, EDX, kDeoptEqualityNoFeedback);
1985 __ j(NOT_EQUAL, deopt_blob->label()); 1982 __ j(NOT_EQUAL, deopt_blob->label());
1986 } else { 1983 } else {
1987 DeoptimizationBlob* deopt_blob = 1984 DeoptimizationBlob* deopt_blob =
1988 AddDeoptimizationBlob(node, EAX, EDX, kDeoptEqualityClassCheck); 1985 AddDeoptimizationBlob(node, EAX, EDX, kDeoptEqualityClassCheck);
1989 __ j(EQUAL, &compare); 1986 __ j(EQUAL, &compare);
1990 // Smi causes deoptimization. 1987 // Smi causes deoptimization.
1991 __ testl(EAX, Immediate(kSmiTagMask)); 1988 __ testl(EAX, Immediate(kSmiTagMask));
1992 __ j(ZERO, deopt_blob->label()); 1989 __ j(ZERO, deopt_blob->label());
1993 __ LoadClassIndexOfObject(EBX, EAX); 1990 __ LoadClassId(EBX, EAX);
1994 for (intptr_t i = 0; i < num_classes; i++) { 1991 for (intptr_t i = 0; i < num_classes; i++) {
1995 const Class& cls = *(*classes)[i]; 1992 const Class& cls = *(*classes)[i];
1996 __ cmpl(EBX, Immediate(cls.index())); 1993 __ cmpl(EBX, Immediate(cls.index()));
1997 if (i == (num_classes - 1)) { 1994 if (i == (num_classes - 1)) {
1998 __ j(NOT_EQUAL, deopt_blob->label()); 1995 __ j(NOT_EQUAL, deopt_blob->label());
1999 } else { 1996 } else {
2000 __ j(EQUAL, &compare); 1997 __ j(EQUAL, &compare);
2001 } 1998 }
2002 } 1999 }
2003 } 2000 }
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
2164 CodeGenInfo index_info(node->index_expr()); 2161 CodeGenInfo index_info(node->index_expr());
2165 VisitLoadTwo(node->array(), node->index_expr(), EBX, EDX); 2162 VisitLoadTwo(node->array(), node->index_expr(), EBX, EDX);
2166 DeoptimizationBlob* deopt_blob = 2163 DeoptimizationBlob* deopt_blob =
2167 AddDeoptimizationBlob(node, EBX, EDX, kDeoptLoadIndexedFixedArray); 2164 AddDeoptimizationBlob(node, EBX, EDX, kDeoptLoadIndexedFixedArray);
2168 const Class& test_class = NodeHasClassAt(node, object_array_class, 0) ? 2165 const Class& test_class = NodeHasClassAt(node, object_array_class, 0) ?
2169 object_array_class : immutable_object_array_class; 2166 object_array_class : immutable_object_array_class;
2170 // Type checks of array. 2167 // Type checks of array.
2171 if (!array_info.IsClass(test_class)) { 2168 if (!array_info.IsClass(test_class)) {
2172 __ testl(EBX, Immediate(kSmiTagMask)); // Deoptimize if Smi. 2169 __ testl(EBX, Immediate(kSmiTagMask)); // Deoptimize if Smi.
2173 __ j(ZERO, deopt_blob->label()); 2170 __ j(ZERO, deopt_blob->label());
2174 __ CompareClassOfObject(EBX, test_class, EAX); 2171 __ CompareClassId(EBX, test_class.index(), EAX);
2175 __ j(NOT_EQUAL, deopt_blob->label()); 2172 __ j(NOT_EQUAL, deopt_blob->label());
2176 PropagateBackLocalClass(node->array(), test_class); 2173 PropagateBackLocalClass(node->array(), test_class);
2177 } 2174 }
2178 2175
2179 // Type check of index. 2176 // Type check of index.
2180 if (!index_info.IsClass(smi_class_)) { 2177 if (!index_info.IsClass(smi_class_)) {
2181 __ testl(EDX, Immediate(kSmiTagMask)); 2178 __ testl(EDX, Immediate(kSmiTagMask));
2182 __ j(NOT_ZERO, deopt_blob->label()); 2179 __ j(NOT_ZERO, deopt_blob->label());
2183 PropagateBackLocalClass(node->index_expr(), smi_class_); 2180 PropagateBackLocalClass(node->index_expr(), smi_class_);
2184 } 2181 }
(...skipping 16 matching lines...) Expand all
2201 AddDeoptimizationBlob(node, EDX, EAX, kDeoptLoadIndexedGrowableArray); 2198 AddDeoptimizationBlob(node, EDX, EAX, kDeoptLoadIndexedGrowableArray);
2202 // EAX: index, EDX: array. 2199 // EAX: index, EDX: array.
2203 if (!index_info.IsClass(smi_class_)) { 2200 if (!index_info.IsClass(smi_class_)) {
2204 __ testl(EAX, Immediate(kSmiTagMask)); 2201 __ testl(EAX, Immediate(kSmiTagMask));
2205 __ j(NOT_ZERO, deopt_blob->label()); // Not Smi index. 2202 __ j(NOT_ZERO, deopt_blob->label()); // Not Smi index.
2206 PropagateBackLocalClass(node->index_expr(), smi_class_); 2203 PropagateBackLocalClass(node->index_expr(), smi_class_);
2207 } 2204 }
2208 if (!array_info.IsClass(growable_object_array_class_)) { 2205 if (!array_info.IsClass(growable_object_array_class_)) {
2209 __ testl(EDX, Immediate(kSmiTagMask)); 2206 __ testl(EDX, Immediate(kSmiTagMask));
2210 __ j(ZERO, deopt_blob->label()); // Array is Smi. 2207 __ j(ZERO, deopt_blob->label()); // Array is Smi.
2211 __ CompareClassOfObject(EDX, growable_object_array_class_, EBX); 2208 __ CompareClassId(EDX, kGrowableObjectArray, EBX);
2212 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray. 2209 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray.
2213 PropagateBackLocalClass(node->array(), growable_object_array_class_); 2210 PropagateBackLocalClass(node->array(), growable_object_array_class_);
2214 } 2211 }
2215 // Range check: deoptimize if out of bounds. 2212 // Range check: deoptimize if out of bounds.
2216 __ cmpl(EAX, FieldAddress(EDX, GrowableObjectArray::length_offset())); 2213 __ cmpl(EAX, FieldAddress(EDX, GrowableObjectArray::length_offset()));
2217 __ j(ABOVE_EQUAL, deopt_blob->label()); 2214 __ j(ABOVE_EQUAL, deopt_blob->label());
2218 __ movl(EDX, FieldAddress(EDX, GrowableObjectArray::data_offset())); 2215 __ movl(EDX, FieldAddress(EDX, GrowableObjectArray::data_offset()));
2219 // Note that EAX is Smi, i.e, times 2. 2216 // Note that EAX is Smi, i.e, times 2.
2220 ASSERT(kSmiTagShift == 1); 2217 ASSERT(kSmiTagShift == 1);
2221 __ movl(EAX, FieldAddress(EDX, EAX, TIMES_2, sizeof(RawArray))); 2218 __ movl(EAX, FieldAddress(EDX, EAX, TIMES_2, sizeof(RawArray)));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2268 VisitLoadOne(node->value(), ECX); 2265 VisitLoadOne(node->value(), ECX);
2269 DeoptimizationBlob* deopt_blob = 2266 DeoptimizationBlob* deopt_blob =
2270 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed); 2267 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed);
2271 __ popl(EBX); // index. 2268 __ popl(EBX); // index.
2272 __ popl(EAX); // array. 2269 __ popl(EAX); // array.
2273 // ECX: value, EBX:index, EAX: array. 2270 // ECX: value, EBX:index, EAX: array.
2274 // Check class of array. 2271 // Check class of array.
2275 if (class_of_this_array.raw() != object_array_class.raw()) { 2272 if (class_of_this_array.raw() != object_array_class.raw()) {
2276 __ testl(EAX, Immediate(kSmiTagMask)); 2273 __ testl(EAX, Immediate(kSmiTagMask));
2277 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt. 2274 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt.
2278 __ CompareClassOfObject(EAX, object_array_class, EDX); 2275 __ CompareClassId(EAX, kArray, EDX);
2279 __ j(NOT_EQUAL, deopt_blob->label()); // Not ObjectArray -> deopt. 2276 __ j(NOT_EQUAL, deopt_blob->label()); // Not ObjectArray -> deopt.
2280 PropagateBackLocalClass(node->array(), object_array_class); 2277 PropagateBackLocalClass(node->array(), object_array_class);
2281 } 2278 }
2282 // Check class of index. 2279 // Check class of index.
2283 if (!index_is_smi) { 2280 if (!index_is_smi) {
2284 __ testl(EBX, Immediate(kSmiTagMask)); 2281 __ testl(EBX, Immediate(kSmiTagMask));
2285 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt. 2282 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
2286 PropagateBackLocalClass(node->index_expr(), smi_class_); 2283 PropagateBackLocalClass(node->index_expr(), smi_class_);
2287 } 2284 }
2288 // Range check. 2285 // Range check.
(...skipping 19 matching lines...) Expand all
2308 VisitLoadOne(node->value(), ECX); 2305 VisitLoadOne(node->value(), ECX);
2309 DeoptimizationBlob* deopt_blob = 2306 DeoptimizationBlob* deopt_blob =
2310 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed); 2307 AddDeoptimizationBlob(node, EAX, EBX, ECX, kDeoptStoreIndexed);
2311 __ popl(EBX); // index. 2308 __ popl(EBX); // index.
2312 __ popl(EAX); // array. 2309 __ popl(EAX); // array.
2313 // ECX: value, EBX:index, EAX: array, EDX: scratch. 2310 // ECX: value, EBX:index, EAX: array, EDX: scratch.
2314 // Check class of array. 2311 // Check class of array.
2315 if (class_of_this_array.raw() != growable_object_array_class_.raw()) { 2312 if (class_of_this_array.raw() != growable_object_array_class_.raw()) {
2316 __ testl(EAX, Immediate(kSmiTagMask)); 2313 __ testl(EAX, Immediate(kSmiTagMask));
2317 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt. 2314 __ j(ZERO, deopt_blob->label()); // Array is smi -> deopt.
2318 __ CompareClassOfObject(EAX, growable_object_array_class_, EDX); 2315 __ CompareClassId(EAX, kGrowableObjectArray, EDX);
2319 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray. 2316 __ j(NOT_EQUAL, deopt_blob->label()); // Not GrowableObjectArray.
2320 PropagateBackLocalClass(node->array(), growable_object_array_class_); 2317 PropagateBackLocalClass(node->array(), growable_object_array_class_);
2321 } 2318 }
2322 // Check class of index. 2319 // Check class of index.
2323 if (!index_is_smi) { 2320 if (!index_is_smi) {
2324 __ testl(EBX, Immediate(kSmiTagMask)); 2321 __ testl(EBX, Immediate(kSmiTagMask));
2325 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt. 2322 __ j(NOT_ZERO, deopt_blob->label()); // Index not Smi -> deopt.
2326 PropagateBackLocalClass(node->index_expr(), smi_class_); 2323 PropagateBackLocalClass(node->index_expr(), smi_class_);
2327 } 2324 }
2328 // Range check: deoptimize if out of bounds. 2325 // Range check: deoptimize if out of bounds.
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
2636 __ jmp(&done); 2633 __ jmp(&done);
2637 __ Bind(&not_smi); // Continue with other test below. 2634 __ Bind(&not_smi); // Continue with other test below.
2638 } else if (NodeMayBeSmi(receiver)) { 2635 } else if (NodeMayBeSmi(receiver)) {
2639 DeoptimizationBlob* deopt_blob = 2636 DeoptimizationBlob* deopt_blob =
2640 AddDeoptimizationBlob(node, kDeoptCheckedInstanceCallSmiFail); 2637 AddDeoptimizationBlob(node, kDeoptCheckedInstanceCallSmiFail);
2641 __ testl(EAX, Immediate(kSmiTagMask)); 2638 __ testl(EAX, Immediate(kSmiTagMask));
2642 __ j(ZERO, deopt_blob->label()); 2639 __ j(ZERO, deopt_blob->label());
2643 } else { 2640 } else {
2644 // Receiver cannot be Smi, no need to test it. 2641 // Receiver cannot be Smi, no need to test it.
2645 } 2642 }
2646 __ LoadClassIndexOfObject(EAX, EAX); // Receiver's class. 2643 __ LoadClassId(EAX, EAX); // Receiver's class id.
2647 for (intptr_t i = start_ix; i < classes.length(); i++) { 2644 for (intptr_t i = start_ix; i < classes.length(); i++) {
2648 const Class& cls = *classes[i]; 2645 const Class& cls = *classes[i];
2649 const Function& target = *targets[i]; 2646 const Function& target = *targets[i];
2650 __ cmpl(EAX, Immediate(cls.index())); 2647 __ cmpl(EAX, Immediate(cls.index()));
2651 if (i == (classes.length() - 1)) { 2648 if (i == (classes.length() - 1)) {
2652 // Last check. 2649 // Last check.
2653 DeoptimizationBlob* deopt_blob = 2650 DeoptimizationBlob* deopt_blob =
2654 AddDeoptimizationBlob(node, kDeoptCheckedInstanceCallCheckFail); 2651 AddDeoptimizationBlob(node, kDeoptCheckedInstanceCallCheckFail);
2655 __ j(NOT_EQUAL, deopt_blob->label()); 2652 __ j(NOT_EQUAL, deopt_blob->label());
2656 GenerateDirectCall(node->id(), 2653 GenerateDirectCall(node->id(),
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
2897 } 2894 }
2898 } 2895 }
2899 // TODO(srdjan): Implement unary kSUB (negate) Mint. 2896 // TODO(srdjan): Implement unary kSUB (negate) Mint.
2900 CodeGenerator::VisitUnaryOpNode(node); 2897 CodeGenerator::VisitUnaryOpNode(node);
2901 } 2898 }
2902 2899
2903 2900
2904 } // namespace dart 2901 } // namespace dart
2905 2902
2906 #endif // defined TARGET_ARCH_IA32 2903 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_ia32.cc ('k') | runtime/vm/stub_code_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698