| OLD | NEW |
| 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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 Label* label() { return &label_; } | 140 Label* label() { return &label_; } |
| 141 | 141 |
| 142 private: | 142 private: |
| 143 const AstNode* node_; | 143 const AstNode* node_; |
| 144 GrowableArray<Register> registers_; | 144 GrowableArray<Register> registers_; |
| 145 Label label_; | 145 Label label_; |
| 146 | 146 |
| 147 DISALLOW_COPY_AND_ASSIGN(DeoptimizationBlob); | 147 DISALLOW_COPY_AND_ASSIGN(DeoptimizationBlob); |
| 148 }; | 148 }; |
| 149 | 149 |
| 150 // TODO(srdjan): Add String_get:length, String_charCodeAt, String_hashCode. | 150 // TODO(srdjan): Add String_charCodeAt, String_hashCode. |
| 151 | 151 |
| 152 #define RECOGNIZED_LIST(V) \ | 152 #define RECOGNIZED_LIST(V) \ |
| 153 V(ObjectArray, get:length, ObjectArrayLength) \ | 153 V(ObjectArray, get:length, ObjectArrayLength) \ |
| 154 V(GrowableObjectArray, get:length, GrowableArrayLength) \ | 154 V(GrowableObjectArray, get:length, GrowableArrayLength) \ |
| 155 V(StringBase, get:length, StringBaseLength) \ |
| 155 V(IntegerImplementation, toDouble, IntegerToDouble) \ | 156 V(IntegerImplementation, toDouble, IntegerToDouble) \ |
| 156 V(Double, toDouble, DoubleToDouble) \ | 157 V(Double, toDouble, DoubleToDouble) \ |
| 157 V(Math, sqrt, MathSqrt) \ | 158 V(Math, sqrt, MathSqrt) \ |
| 158 | 159 |
| 159 // Class that recognizes the name and owner of a function and returns the | 160 // Class that recognizes the name and owner of a function and returns the |
| 160 // corresponding enum. See RECOGNIZED_LIST above for list of recognizable | 161 // corresponding enum. See RECOGNIZED_LIST above for list of recognizable |
| 161 // functions. | 162 // functions. |
| 162 class Recognizer : public AllStatic { | 163 class Recognizer : public AllStatic { |
| 163 public: | 164 public: |
| 164 enum Kind { | 165 enum Kind { |
| 165 kUnknown, | 166 kUnknown, |
| 166 #define DEFINE_ENUM_LIST(class_name, function_name, enum_name) k##enum_name, | 167 #define DEFINE_ENUM_LIST(class_name, function_name, enum_name) k##enum_name, |
| 167 RECOGNIZED_LIST(DEFINE_ENUM_LIST) | 168 RECOGNIZED_LIST(DEFINE_ENUM_LIST) |
| 168 #undef DEFINE_ENUM_LIST | 169 #undef DEFINE_ENUM_LIST |
| 169 }; | 170 }; |
| 170 | 171 |
| 172 // TODO(srdjan): Check that the library is the coreimpl one. |
| 171 static Kind RecognizeKind(const Function& function) { | 173 static Kind RecognizeKind(const Function& function) { |
| 172 const String& recognize_name = String::Handle(function.name()); | 174 const String& recognize_name = String::Handle(function.name()); |
| 173 const String& recognize_class = | 175 const String& recognize_class = |
| 174 String::Handle(Class::Handle(function.owner()).Name()); | 176 String::Handle(Class::Handle(function.owner()).Name()); |
| 175 String& test_function_name = String::Handle(); | 177 String& test_function_name = String::Handle(); |
| 176 String& test_class_name = String::Handle(); | 178 String& test_class_name = String::Handle(); |
| 177 #define RECOGNIZE_FUNCTION(class_name, function_name, enum_name) \ | 179 #define RECOGNIZE_FUNCTION(class_name, function_name, enum_name) \ |
| 178 test_function_name = String::NewSymbol(#function_name); \ | 180 test_function_name = String::NewSymbol(#function_name); \ |
| 179 test_class_name = String::NewSymbol(#class_name); \ | 181 test_class_name = String::NewSymbol(#class_name); \ |
| 180 if (recognize_name.Equals(test_function_name) && \ | 182 if (recognize_name.Equals(test_function_name) && \ |
| (...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1327 return; | 1329 return; |
| 1328 } | 1330 } |
| 1329 case Recognizer::kGrowableArrayLength: { | 1331 case Recognizer::kGrowableArrayLength: { |
| 1330 TraceOpt(node, "Inlines GrowableObjectArray.length"); | 1332 TraceOpt(node, "Inlines GrowableObjectArray.length"); |
| 1331 intptr_t field_offset = GetFieldOffset( | 1333 intptr_t field_offset = GetFieldOffset( |
| 1332 cls, | 1334 cls, |
| 1333 String::Handle(String::NewSymbol(kGrowableArrayLengthFieldName))); | 1335 String::Handle(String::NewSymbol(kGrowableArrayLengthFieldName))); |
| 1334 __ movl(EAX, FieldAddress(EBX, field_offset)); | 1336 __ movl(EAX, FieldAddress(EBX, field_offset)); |
| 1335 return; | 1337 return; |
| 1336 } | 1338 } |
| 1339 case Recognizer::kStringBaseLength: { |
| 1340 TraceOpt(node, "Inlines StringBase.length"); |
| 1341 __ movl(EAX, FieldAddress(EBX, String::length_offset())); |
| 1342 return; |
| 1343 } |
| 1337 default: | 1344 default: |
| 1338 UNIMPLEMENTED(); | 1345 UNIMPLEMENTED(); |
| 1339 } | 1346 } |
| 1340 UNREACHABLE(); | 1347 UNREACHABLE(); |
| 1341 } | 1348 } |
| 1342 | 1349 |
| 1343 | 1350 |
| 1344 static bool IsInlineableInstanceGetter(const Function& function) { | 1351 static bool IsInlineableInstanceGetter(const Function& function) { |
| 1345 if (function.kind() == RawFunction::kImplicitGetter) { | 1352 if (function.kind() == RawFunction::kImplicitGetter) { |
| 1346 return true; | 1353 return true; |
| 1347 } | 1354 } |
| 1348 Recognizer::Kind recognized = Recognizer::RecognizeKind(function); | 1355 Recognizer::Kind recognized = Recognizer::RecognizeKind(function); |
| 1349 if ((recognized == Recognizer::kObjectArrayLength) || | 1356 if ((recognized == Recognizer::kObjectArrayLength) || |
| 1350 (recognized == Recognizer::kGrowableArrayLength)) { | 1357 (recognized == Recognizer::kGrowableArrayLength) || |
| 1358 (recognized == Recognizer::kStringBaseLength)) { |
| 1351 return true; | 1359 return true; |
| 1352 } | 1360 } |
| 1353 return false; | 1361 return false; |
| 1354 } | 1362 } |
| 1355 | 1363 |
| 1356 | 1364 |
| 1357 // Return the unique target of all checks or null. | 1365 // Return the unique target of all checks or null. |
| 1358 static RawFunction* GetUniqueTarget(const ICData& ic_data) { | 1366 static RawFunction* GetUniqueTarget(const ICData& ic_data) { |
| 1359 Function& prev_target = Function::Handle(); | 1367 Function& prev_target = Function::Handle(); |
| 1360 Function& target = Function::Handle(); | 1368 Function& target = Function::Handle(); |
| (...skipping 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2439 __ addl(ESP, Immediate(node->arguments()->length() * kWordSize)); | 2447 __ addl(ESP, Immediate(node->arguments()->length() * kWordSize)); |
| 2440 // Result is in EAX. | 2448 // Result is in EAX. |
| 2441 if (IsResultNeeded(node)) { | 2449 if (IsResultNeeded(node)) { |
| 2442 __ pushl(EAX); | 2450 __ pushl(EAX); |
| 2443 } | 2451 } |
| 2444 } | 2452 } |
| 2445 | 2453 |
| 2446 } // namespace dart | 2454 } // namespace dart |
| 2447 | 2455 |
| 2448 #endif // defined TARGET_ARCH_IA32 | 2456 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |