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

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

Issue 9581016: It is the setter that can have a result, but not the StoreInstanceFieldNode. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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/code_generator_x64.cc ('k') | no next file » | 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 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 const Class* cls = NULL; 558 const Class* cls = NULL;
559 classes_for_locals_->GetLocalClass(node->local(), &cls); 559 classes_for_locals_->GetLocalClass(node->local(), &cls);
560 if (cls != NULL) { 560 if (cls != NULL) {
561 node->info()->set_is_class(cls); 561 node->info()->set_is_class(cls);
562 } 562 }
563 } 563 }
564 } 564 }
565 565
566 566
567 void OptimizingCodeGenerator::HandleResult(AstNode* node, Register result_reg) { 567 void OptimizingCodeGenerator::HandleResult(AstNode* node, Register result_reg) {
568 if (CodeGenerator::IsResultNeeded(node)) { 568 if (IsResultNeeded(node)) {
569 if (IsResultInEaxRequested(node)) { 569 if (IsResultInEaxRequested(node)) {
570 if (result_reg != EAX) { 570 if (result_reg != EAX) {
571 __ movl(EAX, result_reg); 571 __ movl(EAX, result_reg);
572 } 572 }
573 node->info()->set_result_returned_in_eax(true); 573 node->info()->set_result_returned_in_eax(true);
574 } else { 574 } else {
575 __ pushl(result_reg); 575 __ pushl(result_reg);
576 } 576 }
577 } 577 }
578 } 578 }
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 __ movl(kResultRegister, kOperandRegister); 866 __ movl(kResultRegister, kOperandRegister);
867 } else { 867 } else {
868 const Double& double_object = 868 const Double& double_object =
869 Double::ZoneHandle(Double::New(0.0, Heap::kOld)); 869 Double::ZoneHandle(Double::New(0.0, Heap::kOld));
870 __ LoadObject(kResultRegister, double_object); 870 __ LoadObject(kResultRegister, double_object);
871 } 871 }
872 __ movsd(XMM0, FieldAddress(kOperandRegister, Double::value_offset())); 872 __ movsd(XMM0, FieldAddress(kOperandRegister, Double::value_offset()));
873 ASSERT(node->kind() == Token::kSUB); 873 ASSERT(node->kind() == Token::kSUB);
874 __ DoubleNegate(XMM0); 874 __ DoubleNegate(XMM0);
875 __ movsd(FieldAddress(kResultRegister, Double::value_offset()), XMM0); 875 __ movsd(FieldAddress(kResultRegister, Double::value_offset()), XMM0);
876 if (CodeGenerator::IsResultNeeded(node)) { 876 if (IsResultNeeded(node)) {
877 if (node->info() != NULL) { 877 if (node->info() != NULL) {
878 node->info()->set_is_temp(using_temp); 878 node->info()->set_is_temp(using_temp);
879 node->info()->set_is_class(&double_class_); 879 node->info()->set_is_class(&double_class_);
880 } 880 }
881 HandleResult(node, kResultRegister); 881 HandleResult(node, kResultRegister);
882 } 882 }
883 } 883 }
884 884
885 885
886 // Handles only Smi & Smi. 886 // Handles only Smi & Smi.
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 } 1239 }
1240 1240
1241 switch (kind) { 1241 switch (kind) {
1242 case Token::kADD: __ addsd(XMM0, XMM1); break; 1242 case Token::kADD: __ addsd(XMM0, XMM1); break;
1243 case Token::kSUB: __ subsd(XMM0, XMM1); break; 1243 case Token::kSUB: __ subsd(XMM0, XMM1); break;
1244 case Token::kMUL: __ mulsd(XMM0, XMM1); break; 1244 case Token::kMUL: __ mulsd(XMM0, XMM1); break;
1245 case Token::kDIV: __ divsd(XMM0, XMM1); break; 1245 case Token::kDIV: __ divsd(XMM0, XMM1); break;
1246 default: UNREACHABLE(); 1246 default: UNREACHABLE();
1247 } 1247 }
1248 __ movsd(FieldAddress(result_register, Double::value_offset()), XMM0); 1248 __ movsd(FieldAddress(result_register, Double::value_offset()), XMM0);
1249 if (CodeGenerator::IsResultNeeded(node)) { 1249 if (IsResultNeeded(node)) {
1250 if (node->info() != NULL) { 1250 if (node->info() != NULL) {
1251 node->info()->set_is_temp(using_temp); 1251 node->info()->set_is_temp(using_temp);
1252 node->info()->set_is_class(&double_class_); 1252 node->info()->set_is_class(&double_class_);
1253 } 1253 }
1254 HandleResult(node, result_register); 1254 HandleResult(node, result_register);
1255 } 1255 }
1256 return; 1256 return;
1257 } 1257 }
1258 1258
1259 TraceNotOpt(node, kOptMessage); 1259 TraceNotOpt(node, kOptMessage);
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
1999 // Right operand can be Smi or null, otherwise call operator on Smi (e.g, 1999 // Right operand can be Smi or null, otherwise call operator on Smi (e.g,
2000 // when compared with double). 2000 // when compared with double).
2001 // This code will be more optimized once we collect types for two arguments. 2001 // This code will be more optimized once we collect types for two arguments.
2002 void OptimizingCodeGenerator::GenerateSmiEquality(ComparisonNode* node) { 2002 void OptimizingCodeGenerator::GenerateSmiEquality(ComparisonNode* node) {
2003 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 2003 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
2004 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 2004 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
2005 ASSERT((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)); 2005 ASSERT((node->kind() == Token::kEQ) || (node->kind() == Token::kNE));
2006 CodeGenInfo left_info(node->left()); 2006 CodeGenInfo left_info(node->left());
2007 CodeGenInfo right_info(node->right()); 2007 CodeGenInfo right_info(node->right());
2008 VisitLoadTwo(node->left(), node->right(), EAX, EDX); 2008 VisitLoadTwo(node->left(), node->right(), EAX, EDX);
2009 if (!CodeGenerator::IsResultNeeded(node)) { 2009 if (!IsResultNeeded(node)) {
2010 return; 2010 return;
2011 } 2011 }
2012 const Immediate raw_null = 2012 const Immediate raw_null =
2013 Immediate(reinterpret_cast<intptr_t>(Object::null())); 2013 Immediate(reinterpret_cast<intptr_t>(Object::null()));
2014 Label evaluate_comparison; 2014 Label evaluate_comparison;
2015 if (!left_info.IsClass(smi_class_)) { 2015 if (!left_info.IsClass(smi_class_)) {
2016 DeoptimizationBlob* deopt_blob = 2016 DeoptimizationBlob* deopt_blob =
2017 AddDeoptimizationBlob(node, EAX, EDX, kDeoptSmiEquality); 2017 AddDeoptimizationBlob(node, EAX, EDX, kDeoptSmiEquality);
2018 Label left_not_null; 2018 Label left_not_null;
2019 __ cmpl(EAX, raw_null); 2019 __ cmpl(EAX, raw_null);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2092 } 2092 }
2093 Condition condition; 2093 Condition condition;
2094 if (!SupportedTokenKindToSmiCondition(node->kind(), &condition)) { 2094 if (!SupportedTokenKindToSmiCondition(node->kind(), &condition)) {
2095 return false; 2095 return false;
2096 } 2096 }
2097 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 2097 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
2098 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 2098 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
2099 CodeGenInfo left_info(node->left()); 2099 CodeGenInfo left_info(node->left());
2100 CodeGenInfo right_info(node->right()); 2100 CodeGenInfo right_info(node->right());
2101 VisitLoadTwo(node->left(), node->right(), EAX, EDX); 2101 VisitLoadTwo(node->left(), node->right(), EAX, EDX);
2102 if (!CodeGenerator::IsResultNeeded(node)) { 2102 if (!IsResultNeeded(node)) {
2103 return true; 2103 return true;
2104 } 2104 }
2105 if (left_info.IsClass(smi_class_) && right_info.IsClass(smi_class_)) { 2105 if (left_info.IsClass(smi_class_) && right_info.IsClass(smi_class_)) {
2106 __ cmpl(EAX, EDX); 2106 __ cmpl(EAX, EDX);
2107 } else if (left_info.IsClass(smi_class_) || right_info.IsClass(smi_class_)) { 2107 } else if (left_info.IsClass(smi_class_) || right_info.IsClass(smi_class_)) {
2108 // One is Smi. 2108 // One is Smi.
2109 DeoptimizationBlob* deopt_blob = 2109 DeoptimizationBlob* deopt_blob =
2110 AddDeoptimizationBlob(node, EAX, EDX, kDeoptSmiCompareSmis); 2110 AddDeoptimizationBlob(node, EAX, EDX, kDeoptSmiCompareSmis);
2111 Register reg_to_test = left_info.IsClass(smi_class_) ? EDX : EAX; 2111 Register reg_to_test = left_info.IsClass(smi_class_) ? EDX : EAX;
2112 __ testl(reg_to_test, Immediate(kSmiTagMask)); 2112 __ testl(reg_to_test, Immediate(kSmiTagMask));
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2198 if (cls.raw() == smi_class_.raw()) { 2198 if (cls.raw() == smi_class_.raw()) {
2199 // TODO(srdjan): implement mixed smi/non-smi comparison, for the moment 2199 // TODO(srdjan): implement mixed smi/non-smi comparison, for the moment
2200 // bail out. 2200 // bail out.
2201 TraceNotOpt(node, "Equality comparison, mixed with Smi"); 2201 TraceNotOpt(node, "Equality comparison, mixed with Smi");
2202 return false; 2202 return false;
2203 } 2203 }
2204 } 2204 }
2205 2205
2206 // All targets are Object.==, i.e., '==='. Smi is not among the classes. 2206 // All targets are Object.==, i.e., '==='. Smi is not among the classes.
2207 VisitLoadTwo(node->left(), node->right(), EAX, EDX); 2207 VisitLoadTwo(node->left(), node->right(), EAX, EDX);
2208 if (!CodeGenerator::IsResultNeeded(node)) { 2208 if (!IsResultNeeded(node)) {
2209 return true; 2209 return true;
2210 } 2210 }
2211 Label compare; 2211 Label compare;
2212 // Comparison with NULL is "===". 2212 // Comparison with NULL is "===".
2213 const Immediate raw_null = 2213 const Immediate raw_null =
2214 Immediate(reinterpret_cast<intptr_t>(Object::null())); 2214 Immediate(reinterpret_cast<intptr_t>(Object::null()));
2215 __ cmpl(EAX, raw_null); 2215 __ cmpl(EAX, raw_null);
2216 if (num_classes == 0) { 2216 if (num_classes == 0) {
2217 DeoptimizationBlob* deopt_blob = 2217 DeoptimizationBlob* deopt_blob =
2218 AddDeoptimizationBlob(node, EAX, EDX, kDeoptEqualityNoFeedback); 2218 AddDeoptimizationBlob(node, EAX, EDX, kDeoptEqualityNoFeedback);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2292 __ comisd(XMM0, XMM1); 2292 __ comisd(XMM0, XMM1);
2293 if (NodeInfoHasLabels(node)) { 2293 if (NodeInfoHasLabels(node)) {
2294 __ j(PARITY_EVEN, node->info()->false_label()); // NaN -> false; 2294 __ j(PARITY_EVEN, node->info()->false_label()); // NaN -> false;
2295 GenerateConditionalJumps(*(node->info()), true_condition); 2295 GenerateConditionalJumps(*(node->info()), true_condition);
2296 node->info()->set_labels_used(true); 2296 node->info()->set_labels_used(true);
2297 } else { 2297 } else {
2298 Label is_false, is_true, done; 2298 Label is_false, is_true, done;
2299 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false; 2299 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false;
2300 __ j(true_condition, &is_true, Assembler::kNearJump); 2300 __ j(true_condition, &is_true, Assembler::kNearJump);
2301 __ Bind(&is_false); 2301 __ Bind(&is_false);
2302 if (CodeGenerator::IsResultNeeded(node)) { 2302 if (IsResultNeeded(node)) {
2303 __ PushObject(bool_false); 2303 __ PushObject(bool_false);
2304 } 2304 }
2305 __ jmp(&done); 2305 __ jmp(&done);
2306 __ Bind(&is_true); 2306 __ Bind(&is_true);
2307 if (CodeGenerator::IsResultNeeded(node)) { 2307 if (IsResultNeeded(node)) {
2308 __ PushObject(bool_true); 2308 __ PushObject(bool_true);
2309 } 2309 }
2310 __ Bind(&done); 2310 __ Bind(&done);
2311 } 2311 }
2312 return true; 2312 return true;
2313 } 2313 }
2314 2314
2315 2315
2316 // IS, ISNOT are handled in class CodeGenerator. 2316 // IS, ISNOT are handled in class CodeGenerator.
2317 void OptimizingCodeGenerator::VisitComparisonNode(ComparisonNode* node) { 2317 void OptimizingCodeGenerator::VisitComparisonNode(ComparisonNode* node) {
2318 if ((node->kind() == Token::kEQ_STRICT) || 2318 if ((node->kind() == Token::kEQ_STRICT) ||
2319 (node->kind() == Token::kNE_STRICT)) { 2319 (node->kind() == Token::kNE_STRICT)) {
2320 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 2320 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
2321 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 2321 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
2322 // Note that evaluation of right may cause deoptimization, therefore left 2322 // Note that evaluation of right may cause deoptimization, therefore left
2323 // must be on stack when evaluating right. 2323 // must be on stack when evaluating right.
2324 if (node->right()->IsLiteralNode()) { 2324 if (node->right()->IsLiteralNode()) {
2325 VisitLoadOne(node->left(), EAX); 2325 VisitLoadOne(node->left(), EAX);
2326 __ CompareObject(EAX, node->right()->AsLiteralNode()->literal()); 2326 __ CompareObject(EAX, node->right()->AsLiteralNode()->literal());
2327 } else { 2327 } else {
2328 VisitLoadTwo(node->left(), node->right(), EAX, EDX); 2328 VisitLoadTwo(node->left(), node->right(), EAX, EDX);
2329 __ cmpl(EAX, EDX); 2329 __ cmpl(EAX, EDX);
2330 } 2330 }
2331 if (!CodeGenerator::IsResultNeeded(node)) { 2331 if (!IsResultNeeded(node)) {
2332 return; 2332 return;
2333 } 2333 }
2334 Condition condition = node->kind() == Token::kEQ_STRICT ? EQUAL : NOT_EQUAL; 2334 Condition condition = node->kind() == Token::kEQ_STRICT ? EQUAL : NOT_EQUAL;
2335 if (NodeInfoHasLabels(node)) { 2335 if (NodeInfoHasLabels(node)) {
2336 GenerateConditionalJumps(*(node->info()), condition); 2336 GenerateConditionalJumps(*(node->info()), condition);
2337 node->info()->set_labels_used(true); 2337 node->info()->set_labels_used(true);
2338 } else { 2338 } else {
2339 Label done, is_true; 2339 Label done, is_true;
2340 __ j(condition, &is_true); 2340 __ j(condition, &is_true);
2341 __ PushObject(bool_false); 2341 __ PushObject(bool_false);
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after
3090 3090
3091 3091
3092 void OptimizingCodeGenerator::VisitStoreInstanceFieldNode( 3092 void OptimizingCodeGenerator::VisitStoreInstanceFieldNode(
3093 StoreInstanceFieldNode* node) { 3093 StoreInstanceFieldNode* node) {
3094 if (FLAG_enable_type_checks) { 3094 if (FLAG_enable_type_checks) {
3095 CodeGenerator::VisitStoreInstanceFieldNode(node); 3095 CodeGenerator::VisitStoreInstanceFieldNode(node);
3096 return; 3096 return;
3097 } 3097 }
3098 VisitLoadTwo(node->instance(), node->value(), EDX, EAX); 3098 VisitLoadTwo(node->instance(), node->value(), EDX, EAX);
3099 __ StoreIntoObject(EDX, FieldAddress(EDX, node->field().Offset()), EAX); 3099 __ StoreIntoObject(EDX, FieldAddress(EDX, node->field().Offset()), EAX);
3100 // The result is the input value. 3100 ASSERT(!IsResultNeeded(node));
3101 HandleResult(node, EAX);
3102 } 3101 }
3103 3102
3104 3103
3105 void OptimizingCodeGenerator::VisitCatchClauseNode(CatchClauseNode* node) { 3104 void OptimizingCodeGenerator::VisitCatchClauseNode(CatchClauseNode* node) {
3106 // TODO(srdjan): Set classes for locals. 3105 // TODO(srdjan): Set classes for locals.
3107 classes_for_locals_->Clear(); 3106 classes_for_locals_->Clear();
3108 CodeGenerator::VisitCatchClauseNode(node); 3107 CodeGenerator::VisitCatchClauseNode(node);
3109 } 3108 }
3110 3109
3111 3110
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3153 } 3152 }
3154 } 3153 }
3155 // TODO(srdjan): Implement unary kSUB (negate) Mint. 3154 // TODO(srdjan): Implement unary kSUB (negate) Mint.
3156 CodeGenerator::VisitUnaryOpNode(node); 3155 CodeGenerator::VisitUnaryOpNode(node);
3157 } 3156 }
3158 3157
3159 3158
3160 } // namespace dart 3159 } // namespace dart
3161 3160
3162 #endif // defined TARGET_ARCH_IA32 3161 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/code_generator_x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698