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

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

Issue 9288086: Allocate inlined temporary double objects only if the parent node supports it; (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 11 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 | « no previous file | 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 12 matching lines...) Expand all
23 DECLARE_FLAG(bool, enable_type_checks); 23 DECLARE_FLAG(bool, enable_type_checks);
24 DECLARE_FLAG(bool, intrinsify); 24 DECLARE_FLAG(bool, intrinsify);
25 DECLARE_FLAG(bool, trace_functions); 25 DECLARE_FLAG(bool, trace_functions);
26 26
27 27
28 // Property list to be used in CodeGenInfo. Each property has a setter 28 // Property list to be used in CodeGenInfo. Each property has a setter
29 // and a getter of specified type and name. 29 // and a getter of specified type and name.
30 // (name, type, default) 30 // (name, type, default)
31 #define PROPERTY_LIST(V) \ 31 #define PROPERTY_LIST(V) \
32 V(is_temp, bool, false) \ 32 V(is_temp, bool, false) \
33 V(allow_temp, bool, false) \
33 V(true_label, Label*, NULL) \ 34 V(true_label, Label*, NULL) \
34 V(false_label, Label*, NULL) \ 35 V(false_label, Label*, NULL) \
35 V(labels_used, bool, false) \ 36 V(labels_used, bool, false) \
36 V(request_result_in_eax, bool, false) \ 37 V(request_result_in_eax, bool, false) \
37 V(result_returned_in_eax, bool, false) \ 38 V(result_returned_in_eax, bool, false) \
38 V(fallthrough_label, Label*, NULL) \ 39 V(fallthrough_label, Label*, NULL) \
39 V(is_class, const Class*, &Class::ZoneHandle()) \ 40 V(is_class, const Class*, &Class::ZoneHandle()) \
40 41
41 42
42 // Class holding information being passed from source to destination. 43 // Class holding information being passed from source to destination.
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 } 578 }
578 579
579 580
580 void OptimizingCodeGenerator::VisitStoreLocalNode(StoreLocalNode* node) { 581 void OptimizingCodeGenerator::VisitStoreLocalNode(StoreLocalNode* node) {
581 if (FLAG_enable_type_checks) { 582 if (FLAG_enable_type_checks) {
582 CodeGenerator::VisitStoreLocalNode(node); 583 CodeGenerator::VisitStoreLocalNode(node);
583 classes_for_locals_->SetLocalType(node->local(), Class::ZoneHandle()); 584 classes_for_locals_->SetLocalType(node->local(), Class::ZoneHandle());
584 return; 585 return;
585 } 586 }
586 CodeGenInfo value_info(node->value()); 587 CodeGenInfo value_info(node->value());
588 value_info.set_allow_temp(true);
587 value_info.set_request_result_in_eax(true); 589 value_info.set_request_result_in_eax(true);
588 node->value()->Visit(this); 590 node->value()->Visit(this);
589 if (value_info.is_temp()) { 591 if (value_info.is_temp()) {
590 if (value_info.IsClass(double_class_)) { 592 if (value_info.IsClass(double_class_)) {
591 if (value_info.result_returned_in_eax()) { 593 if (value_info.result_returned_in_eax()) {
592 __ pushl(EAX); 594 __ pushl(EAX);
593 } 595 }
594 const Code& stub = 596 const Code& stub =
595 Code::Handle(StubCode::GetAllocationStubForClass(double_class_)); 597 Code::Handle(StubCode::GetAllocationStubForClass(double_class_));
596 const ExternalLabel label(double_class_.ToCString(), stub.EntryPoint()); 598 const ExternalLabel label(double_class_.ToCString(), stub.EntryPoint());
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 __ pushl(kOperandRegister); 875 __ pushl(kOperandRegister);
874 GenerateCall(node->token_index(), &label); 876 GenerateCall(node->token_index(), &label);
875 ASSERT(kResultRegister == EAX); 877 ASSERT(kResultRegister == EAX);
876 __ popl(kOperandRegister); 878 __ popl(kOperandRegister);
877 __ movsd(XMM0, FieldAddress(kOperandRegister, Double::value_offset())); 879 __ movsd(XMM0, FieldAddress(kOperandRegister, Double::value_offset()));
878 __ xorps(XMM1, XMM1); // 0.0 -> XMM1. 880 __ xorps(XMM1, XMM1); // 0.0 -> XMM1.
879 __ subsd(XMM1, XMM0); 881 __ subsd(XMM1, XMM0);
880 __ movsd(FieldAddress(kResultRegister, Double::value_offset()), XMM1); 882 __ movsd(FieldAddress(kResultRegister, Double::value_offset()), XMM1);
881 if (CodeGenerator::IsResultNeeded(node)) { 883 if (CodeGenerator::IsResultNeeded(node)) {
882 if (node->info() != NULL) { 884 if (node->info() != NULL) {
883 node->info()->set_is_temp(true); 885 // TODO(srdjan): Enable once we use a temporary object.
886 // node->info()->set_is_temp(true);
884 node->info()->set_is_class(&double_class_); 887 node->info()->set_is_class(&double_class_);
885 } 888 }
886 HandleResult(node, kResultRegister); 889 HandleResult(node, kResultRegister);
887 } 890 }
888 } 891 }
889 892
890 893
891 // Handles only Smi & Smi. 894 // Handles only Smi & Smi.
892 // TODO(srdjan): Certain operations always overflow, and thus cause 895 // TODO(srdjan): Certain operations always overflow, and thus cause
893 // deoptimization. We need to mark those places and handle them. 896 // deoptimization. We need to mark those places and handle them.
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 (kind == Token::kMUL) || 1133 (kind == Token::kMUL) ||
1131 (kind == Token::kDIV)) { 1134 (kind == Token::kDIV)) {
1132 TraceOpt(node, kOptMessage); 1135 TraceOpt(node, kOptMessage);
1133 // All four register below must be different. 1136 // All four register below must be different.
1134 const Register kLeftRegister = EAX; 1137 const Register kLeftRegister = EAX;
1135 const Register kRightRegister = EDX; 1138 const Register kRightRegister = EDX;
1136 const Register kAllocatedRegister = ECX; 1139 const Register kAllocatedRegister = ECX;
1137 const Register kTempRegister = EBX; 1140 const Register kTempRegister = EBX;
1138 CodeGenInfo left_info(node->left()); // Receiver. 1141 CodeGenInfo left_info(node->left()); // Receiver.
1139 CodeGenInfo right_info(node->right()); 1142 CodeGenInfo right_info(node->right());
1143 left_info.set_allow_temp(true);
1144 right_info.set_allow_temp(true);
1140 VisitLoadTwo(node->left(), node->right(), kLeftRegister, kRightRegister); 1145 VisitLoadTwo(node->left(), node->right(), kLeftRegister, kRightRegister);
1141 // First allocate result object or specify an existing object as result. 1146 // First allocate result object or specify an existing object as result.
1142 Register result_register = kNoRegister; 1147 Register result_register = kNoRegister;
1143 if (node->info() == NULL) { 1148 const bool using_temp =
1149 (node->info() != NULL) && node->info()->allow_temp();
1150 if (!using_temp) {
1144 // Parent node cannot handle a temporary double object, allocate one 1151 // Parent node cannot handle a temporary double object, allocate one
1145 // each time. 1152 // each time.
1146 result_register = kAllocatedRegister; 1153 result_register = kAllocatedRegister;
1147 const Code& stub = 1154 const Code& stub =
1148 Code::Handle(StubCode::GetAllocationStubForClass(double_class_)); 1155 Code::Handle(StubCode::GetAllocationStubForClass(double_class_));
1149 const ExternalLabel label(double_class_.ToCString(), stub.EntryPoint()); 1156 const ExternalLabel label(double_class_.ToCString(), stub.EntryPoint());
1150 __ pushl(kLeftRegister); 1157 __ pushl(kLeftRegister);
1151 __ pushl(kRightRegister); 1158 __ pushl(kRightRegister);
1152 GenerateCall(node->token_index(), &label); 1159 GenerateCall(node->token_index(), &label);
1153 __ movl(result_register, EAX); 1160 __ movl(result_register, EAX);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 switch (kind) { 1246 switch (kind) {
1240 case Token::kADD: __ addsd(XMM0, XMM1); break; 1247 case Token::kADD: __ addsd(XMM0, XMM1); break;
1241 case Token::kSUB: __ subsd(XMM0, XMM1); break; 1248 case Token::kSUB: __ subsd(XMM0, XMM1); break;
1242 case Token::kMUL: __ mulsd(XMM0, XMM1); break; 1249 case Token::kMUL: __ mulsd(XMM0, XMM1); break;
1243 case Token::kDIV: __ divsd(XMM0, XMM1); break; 1250 case Token::kDIV: __ divsd(XMM0, XMM1); break;
1244 default: UNREACHABLE(); 1251 default: UNREACHABLE();
1245 } 1252 }
1246 __ movsd(FieldAddress(result_register, Double::value_offset()), XMM0); 1253 __ movsd(FieldAddress(result_register, Double::value_offset()), XMM0);
1247 if (CodeGenerator::IsResultNeeded(node)) { 1254 if (CodeGenerator::IsResultNeeded(node)) {
1248 if (node->info() != NULL) { 1255 if (node->info() != NULL) {
1249 node->info()->set_is_temp(true); 1256 node->info()->set_is_temp(using_temp);
1250 node->info()->set_is_class(&double_class_); 1257 node->info()->set_is_class(&double_class_);
1251 } 1258 }
1252 HandleResult(node, result_register); 1259 HandleResult(node, result_register);
1253 } 1260 }
1254 return; 1261 return;
1255 } 1262 }
1256 1263
1257 TraceNotOpt(node, kOptMessage); 1264 TraceNotOpt(node, kOptMessage);
1258 CodeGenerator::VisitBinaryOpNode(node); 1265 CodeGenerator::VisitBinaryOpNode(node);
1259 } 1266 }
(...skipping 1861 matching lines...) Expand 10 before | Expand all | Expand 10 after
3121 } 3128 }
3122 } 3129 }
3123 // TODO(srdjan): Implement unary kSUB (negate) Mint. 3130 // TODO(srdjan): Implement unary kSUB (negate) Mint.
3124 CodeGenerator::VisitUnaryOpNode(node); 3131 CodeGenerator::VisitUnaryOpNode(node);
3125 } 3132 }
3126 3133
3127 3134
3128 } // namespace dart 3135 } // namespace dart
3129 3136
3130 #endif // defined TARGET_ARCH_IA32 3137 #endif // defined TARGET_ARCH_IA32
OLDNEW
« 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